cxgb4_cudbg.c 9.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 *  Copyright (C) 2017 Chelsio Communications.  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms and conditions of the GNU General Public License,
 *  version 2, as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 *  more details.
 *
 *  The full GNU General Public License is included in this distribution in
 *  the file called "COPYING".
 *
 */

18
#include "t4_regs.h"
19 20
#include "cxgb4.h"
#include "cxgb4_cudbg.h"
21
#include "cudbg_entity.h"
22

23 24 25 26 27
static const struct cxgb4_collect_entity cxgb4_collect_mem_dump[] = {
	{ CUDBG_EDC0, cudbg_collect_edc0_meminfo },
	{ CUDBG_EDC1, cudbg_collect_edc1_meminfo },
};

R
Rahul Lakkireddy 已提交
28
static const struct cxgb4_collect_entity cxgb4_collect_hw_dump[] = {
29 30
	{ CUDBG_MBOX_LOG, cudbg_collect_mbox_log },
	{ CUDBG_DEV_LOG, cudbg_collect_fw_devlog },
R
Rahul Lakkireddy 已提交
31
	{ CUDBG_REG_DUMP, cudbg_collect_reg_dump },
32 33
	{ CUDBG_CIM_LA, cudbg_collect_cim_la },
	{ CUDBG_CIM_MA_LA, cudbg_collect_cim_ma_la },
34
	{ CUDBG_CIM_QCFG, cudbg_collect_cim_qcfg },
35 36 37 38 39 40 41 42 43 44 45 46
	{ CUDBG_CIM_IBQ_TP0, cudbg_collect_cim_ibq_tp0 },
	{ CUDBG_CIM_IBQ_TP1, cudbg_collect_cim_ibq_tp1 },
	{ CUDBG_CIM_IBQ_ULP, cudbg_collect_cim_ibq_ulp },
	{ CUDBG_CIM_IBQ_SGE0, cudbg_collect_cim_ibq_sge0 },
	{ CUDBG_CIM_IBQ_SGE1, cudbg_collect_cim_ibq_sge1 },
	{ CUDBG_CIM_IBQ_NCSI, cudbg_collect_cim_ibq_ncsi },
	{ CUDBG_CIM_OBQ_ULP0, cudbg_collect_cim_obq_ulp0 },
	{ CUDBG_CIM_OBQ_ULP1, cudbg_collect_cim_obq_ulp1 },
	{ CUDBG_CIM_OBQ_ULP2, cudbg_collect_cim_obq_ulp2 },
	{ CUDBG_CIM_OBQ_ULP3, cudbg_collect_cim_obq_ulp3 },
	{ CUDBG_CIM_OBQ_SGE, cudbg_collect_cim_obq_sge },
	{ CUDBG_CIM_OBQ_NCSI, cudbg_collect_cim_obq_ncsi },
R
Rahul Lakkireddy 已提交
47
	{ CUDBG_TP_INDIRECT, cudbg_collect_tp_indirect },
48
	{ CUDBG_SGE_INDIRECT, cudbg_collect_sge_indirect },
49 50 51
	{ CUDBG_ULPRX_LA, cudbg_collect_ulprx_la },
	{ CUDBG_TP_LA, cudbg_collect_tp_la },
	{ CUDBG_CIM_PIF_LA, cudbg_collect_cim_pif_la },
52 53
	{ CUDBG_CIM_OBQ_RXQ0, cudbg_collect_obq_sge_rx_q0 },
	{ CUDBG_CIM_OBQ_RXQ1, cudbg_collect_obq_sge_rx_q1 },
54 55 56
	{ CUDBG_PCIE_INDIRECT, cudbg_collect_pcie_indirect },
	{ CUDBG_PM_INDIRECT, cudbg_collect_pm_indirect },
	{ CUDBG_MA_INDIRECT, cudbg_collect_ma_indirect },
57
	{ CUDBG_ULPTX_LA, cudbg_collect_ulptx_la },
58 59
	{ CUDBG_UP_CIM_INDIRECT, cudbg_collect_up_cim_indirect },
	{ CUDBG_HMA_INDIRECT, cudbg_collect_hma_indirect },
R
Rahul Lakkireddy 已提交
60 61 62 63
};

static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity)
{
R
Rahul Lakkireddy 已提交
64
	u32 value, n = 0, len = 0;
R
Rahul Lakkireddy 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79

	switch (entity) {
	case CUDBG_REG_DUMP:
		switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
		case CHELSIO_T4:
			len = T4_REGMAP_SIZE;
			break;
		case CHELSIO_T5:
		case CHELSIO_T6:
			len = T5_REGMAP_SIZE;
			break;
		default:
			break;
		}
		break;
80 81 82
	case CUDBG_DEV_LOG:
		len = adap->params.devlog.size;
		break;
83 84 85 86 87 88 89 90 91 92 93 94 95
	case CUDBG_CIM_LA:
		if (is_t6(adap->params.chip)) {
			len = adap->params.cim_la_size / 10 + 1;
			len *= 11 * sizeof(u32);
		} else {
			len = adap->params.cim_la_size / 8;
			len *= 8 * sizeof(u32);
		}
		len += sizeof(u32); /* for reading CIM LA configuration */
		break;
	case CUDBG_CIM_MA_LA:
		len = 2 * CIM_MALA_SIZE * 5 * sizeof(u32);
		break;
96 97 98
	case CUDBG_CIM_QCFG:
		len = sizeof(struct cudbg_cim_qcfg);
		break;
99 100 101 102 103 104 105 106 107
	case CUDBG_CIM_IBQ_TP0:
	case CUDBG_CIM_IBQ_TP1:
	case CUDBG_CIM_IBQ_ULP:
	case CUDBG_CIM_IBQ_SGE0:
	case CUDBG_CIM_IBQ_SGE1:
	case CUDBG_CIM_IBQ_NCSI:
		len = CIM_IBQ_SIZE * 4 * sizeof(u32);
		break;
	case CUDBG_CIM_OBQ_ULP0:
108 109
		len = cudbg_cim_obq_size(adap, 0);
		break;
110
	case CUDBG_CIM_OBQ_ULP1:
111 112
		len = cudbg_cim_obq_size(adap, 1);
		break;
113
	case CUDBG_CIM_OBQ_ULP2:
114 115
		len = cudbg_cim_obq_size(adap, 2);
		break;
116
	case CUDBG_CIM_OBQ_ULP3:
117 118
		len = cudbg_cim_obq_size(adap, 3);
		break;
119
	case CUDBG_CIM_OBQ_SGE:
120 121
		len = cudbg_cim_obq_size(adap, 4);
		break;
122
	case CUDBG_CIM_OBQ_NCSI:
123 124
		len = cudbg_cim_obq_size(adap, 5);
		break;
125
	case CUDBG_CIM_OBQ_RXQ0:
126 127
		len = cudbg_cim_obq_size(adap, 6);
		break;
128
	case CUDBG_CIM_OBQ_RXQ1:
129
		len = cudbg_cim_obq_size(adap, 7);
130
		break;
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
	case CUDBG_EDC0:
		value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
		if (value & EDRAM0_ENABLE_F) {
			value = t4_read_reg(adap, MA_EDRAM0_BAR_A);
			len = EDRAM0_SIZE_G(value);
		}
		len = cudbg_mbytes_to_bytes(len);
		break;
	case CUDBG_EDC1:
		value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
		if (value & EDRAM1_ENABLE_F) {
			value = t4_read_reg(adap, MA_EDRAM1_BAR_A);
			len = EDRAM1_SIZE_G(value);
		}
		len = cudbg_mbytes_to_bytes(len);
		break;
R
Rahul Lakkireddy 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
	case CUDBG_TP_INDIRECT:
		switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
		case CHELSIO_T5:
			n = sizeof(t5_tp_pio_array) +
			    sizeof(t5_tp_tm_pio_array) +
			    sizeof(t5_tp_mib_index_array);
			break;
		case CHELSIO_T6:
			n = sizeof(t6_tp_pio_array) +
			    sizeof(t6_tp_tm_pio_array) +
			    sizeof(t6_tp_mib_index_array);
			break;
		default:
			break;
		}
		n = n / (IREG_NUM_ELEM * sizeof(u32));
		len = sizeof(struct ireg_buf) * n;
		break;
165 166 167
	case CUDBG_SGE_INDIRECT:
		len = sizeof(struct ireg_buf) * 2;
		break;
168 169 170 171 172 173 174 175 176 177
	case CUDBG_ULPRX_LA:
		len = sizeof(struct cudbg_ulprx_la);
		break;
	case CUDBG_TP_LA:
		len = sizeof(struct cudbg_tp_la) + TPLA_SIZE * sizeof(u64);
		break;
	case CUDBG_CIM_PIF_LA:
		len = sizeof(struct cudbg_cim_pif_la);
		len += 2 * CIM_PIFLA_SIZE * 6 * sizeof(u32);
		break;
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	case CUDBG_PCIE_INDIRECT:
		n = sizeof(t5_pcie_pdbg_array) / (IREG_NUM_ELEM * sizeof(u32));
		len = sizeof(struct ireg_buf) * n * 2;
		break;
	case CUDBG_PM_INDIRECT:
		n = sizeof(t5_pm_rx_array) / (IREG_NUM_ELEM * sizeof(u32));
		len = sizeof(struct ireg_buf) * n * 2;
		break;
	case CUDBG_MA_INDIRECT:
		if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
			n = sizeof(t6_ma_ireg_array) /
			    (IREG_NUM_ELEM * sizeof(u32));
			len = sizeof(struct ireg_buf) * n * 2;
		}
		break;
193 194 195
	case CUDBG_ULPTX_LA:
		len = sizeof(struct cudbg_ulptx_la);
		break;
196 197 198 199
	case CUDBG_UP_CIM_INDIRECT:
		n = sizeof(t5_up_cim_reg_array) / (IREG_NUM_ELEM * sizeof(u32));
		len = sizeof(struct ireg_buf) * n;
		break;
200 201 202
	case CUDBG_MBOX_LOG:
		len = sizeof(struct cudbg_mbox_log) * adap->mbox_log->size;
		break;
203 204 205 206 207 208 209
	case CUDBG_HMA_INDIRECT:
		if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
			n = sizeof(t6_hma_ireg_array) /
			    (IREG_NUM_ELEM * sizeof(u32));
			len = sizeof(struct ireg_buf) * n;
		}
		break;
R
Rahul Lakkireddy 已提交
210 211 212 213 214 215 216
	default:
		break;
	}

	return len;
}

217 218
u32 cxgb4_get_dump_length(struct adapter *adap, u32 flag)
{
R
Rahul Lakkireddy 已提交
219 220 221 222 223 224 225 226 227 228
	u32 i, entity;
	u32 len = 0;

	if (flag & CXGB4_ETH_DUMP_HW) {
		for (i = 0; i < ARRAY_SIZE(cxgb4_collect_hw_dump); i++) {
			entity = cxgb4_collect_hw_dump[i].entity;
			len += cxgb4_get_entity_length(adap, entity);
		}
	}

229 230 231 232 233 234 235
	if (flag & CXGB4_ETH_DUMP_MEM) {
		for (i = 0; i < ARRAY_SIZE(cxgb4_collect_mem_dump); i++) {
			entity = cxgb4_collect_mem_dump[i].entity;
			len += cxgb4_get_entity_length(adap, entity);
		}
	}

R
Rahul Lakkireddy 已提交
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
	return len;
}

static void cxgb4_cudbg_collect_entity(struct cudbg_init *pdbg_init,
				       struct cudbg_buffer *dbg_buff,
				       const struct cxgb4_collect_entity *e_arr,
				       u32 arr_size, void *buf, u32 *tot_size)
{
	struct adapter *adap = pdbg_init->adap;
	struct cudbg_error cudbg_err = { 0 };
	struct cudbg_entity_hdr *entity_hdr;
	u32 entity_size, i;
	u32 total_size = 0;
	int ret;

	for (i = 0; i < arr_size; i++) {
		const struct cxgb4_collect_entity *e = &e_arr[i];

		/* Skip entities that won't fit in output buffer */
		entity_size = cxgb4_get_entity_length(adap, e->entity);
		if (entity_size >
		    pdbg_init->outbuf_size - *tot_size - total_size)
			continue;

		entity_hdr = cudbg_get_entity_hdr(buf, e->entity);
		entity_hdr->entity_type = e->entity;
		entity_hdr->start_offset = dbg_buff->offset;
		memset(&cudbg_err, 0, sizeof(struct cudbg_error));
		ret = e->collect_cb(pdbg_init, dbg_buff, &cudbg_err);
		if (ret) {
			entity_hdr->size = 0;
			dbg_buff->offset = entity_hdr->start_offset;
		} else {
			cudbg_align_debug_buffer(dbg_buff, entity_hdr);
		}

		/* Log error and continue with next entity */
		if (cudbg_err.sys_err)
			ret = CUDBG_SYSTEM_ERROR;

		entity_hdr->hdr_flags = ret;
		entity_hdr->sys_err = cudbg_err.sys_err;
		entity_hdr->sys_warn = cudbg_err.sys_warn;
		total_size += entity_hdr->size;
	}

	*tot_size += total_size;
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
}

int cxgb4_cudbg_collect(struct adapter *adap, void *buf, u32 *buf_size,
			u32 flag)
{
	struct cudbg_init cudbg_init = { 0 };
	struct cudbg_buffer dbg_buff = { 0 };
	u32 size, min_size, total_size = 0;
	struct cudbg_hdr *cudbg_hdr;

	size = *buf_size;

	cudbg_init.adap = adap;
	cudbg_init.outbuf = buf;
	cudbg_init.outbuf_size = size;

	dbg_buff.data = buf;
	dbg_buff.size = size;
	dbg_buff.offset = 0;

	cudbg_hdr = (struct cudbg_hdr *)buf;
	cudbg_hdr->signature = CUDBG_SIGNATURE;
	cudbg_hdr->hdr_len = sizeof(struct cudbg_hdr);
	cudbg_hdr->major_ver = CUDBG_MAJOR_VERSION;
	cudbg_hdr->minor_ver = CUDBG_MINOR_VERSION;
	cudbg_hdr->max_entities = CUDBG_MAX_ENTITY;
	cudbg_hdr->chip_ver = adap->params.chip;
	cudbg_hdr->dump_type = CUDBG_DUMP_TYPE_MINI;
	cudbg_hdr->compress_type = CUDBG_COMPRESSION_NONE;

	min_size = sizeof(struct cudbg_hdr) +
		   sizeof(struct cudbg_entity_hdr) *
		   cudbg_hdr->max_entities;
	if (size < min_size)
		return -ENOMEM;

	dbg_buff.offset += min_size;
	total_size = dbg_buff.offset;

R
Rahul Lakkireddy 已提交
322 323 324 325 326 327 328
	if (flag & CXGB4_ETH_DUMP_HW)
		cxgb4_cudbg_collect_entity(&cudbg_init, &dbg_buff,
					   cxgb4_collect_hw_dump,
					   ARRAY_SIZE(cxgb4_collect_hw_dump),
					   buf,
					   &total_size);

329 330 331 332 333 334 335
	if (flag & CXGB4_ETH_DUMP_MEM)
		cxgb4_cudbg_collect_entity(&cudbg_init, &dbg_buff,
					   cxgb4_collect_mem_dump,
					   ARRAY_SIZE(cxgb4_collect_mem_dump),
					   buf,
					   &total_size);

336 337 338 339 340 341 342 343 344 345 346
	cudbg_hdr->data_len = total_size;
	*buf_size = total_size;
	return 0;
}

void cxgb4_init_ethtool_dump(struct adapter *adapter)
{
	adapter->eth_dump.flag = CXGB4_ETH_DUMP_NONE;
	adapter->eth_dump.version = adapter->params.fw_vers;
	adapter->eth_dump.len = 0;
}