17e6ad46Vishal Kulkarni/*
27e6ad46Vishal Kulkarni * This file and its contents are supplied under the terms of the
37e6ad46Vishal Kulkarni * Common Development and Distribution License ("CDDL"), version 1.0.
47e6ad46Vishal Kulkarni * You may only use this file in accordance with the terms of version
57e6ad46Vishal Kulkarni * 1.0 of the CDDL.
67e6ad46Vishal Kulkarni *
77e6ad46Vishal Kulkarni * A full copy of the text of the CDDL should have accompanied this
87e6ad46Vishal Kulkarni * source. A copy of the CDDL is also available via the Internet at
97e6ad46Vishal Kulkarni * http://www.illumos.org/license/CDDL.
107e6ad46Vishal Kulkarni */
117e6ad46Vishal Kulkarni
127e6ad46Vishal Kulkarni/*-
137e6ad46Vishal Kulkarni * Copyright (c) 2019 Chelsio Communications, Inc.
147e6ad46Vishal Kulkarni * All rights reserved.
157e6ad46Vishal Kulkarni *
167e6ad46Vishal Kulkarni * Redistribution and use in source and binary forms, with or without
177e6ad46Vishal Kulkarni * modification, are permitted provided that the following conditions
187e6ad46Vishal Kulkarni * are met:
197e6ad46Vishal Kulkarni * 1. Redistributions of source code must retain the above copyright
207e6ad46Vishal Kulkarni *    notice, this list of conditions and the following disclaimer.
217e6ad46Vishal Kulkarni * 2. Redistributions in binary form must reproduce the above copyright
227e6ad46Vishal Kulkarni *    notice, this list of conditions and the following disclaimer in the
237e6ad46Vishal Kulkarni *    documentation and/or other materials provided with the distribution.
247e6ad46Vishal Kulkarni *
357e6ad46Vishal Kulkarni * SUCH DAMAGE.
367e6ad46Vishal Kulkarni */
377e6ad46Vishal Kulkarni
387e6ad46Vishal Kulkarni#include <sys/types.h>
397e6ad46Vishal Kulkarni#include <sys/param.h>
407e6ad46Vishal Kulkarni
417e6ad46Vishal Kulkarni#include "common/common.h"
427e6ad46Vishal Kulkarni#include "common/t4_regs.h"
437e6ad46Vishal Kulkarni#include "common/t4_chip_type.h"
447e6ad46Vishal Kulkarni#include "cudbg.h"
457e6ad46Vishal Kulkarni#include "cudbg_lib_common.h"
467e6ad46Vishal Kulkarni#include "cudbg_lib.h"
477e6ad46Vishal Kulkarni#include "cudbg_entity.h"
487e6ad46Vishal Kulkarni
497e6ad46Vishal Kulkarni#define  BUFFER_WARN_LIMIT 10000000
507e6ad46Vishal Kulkarni
517e6ad46Vishal Kulkarnistruct large_entity large_entity_list[] = {
527e6ad46Vishal Kulkarni	{CUDBG_EDC0, 0, 0},
537e6ad46Vishal Kulkarni	{CUDBG_EDC1, 0 , 0},
547e6ad46Vishal Kulkarni	{CUDBG_MC0, 0, 0},
557e6ad46Vishal Kulkarni	{CUDBG_MC1, 0, 0}
567e6ad46Vishal Kulkarni};
577e6ad46Vishal Kulkarni
587e6ad46Vishal Kulkarnistatic int
597e6ad46Vishal Kulkarniis_fw_attached(struct cudbg_init *pdbg_init)
607e6ad46Vishal Kulkarni{
617e6ad46Vishal Kulkarni
627e6ad46Vishal Kulkarni	return (pdbg_init->adap->flags & FW_OK);
637e6ad46Vishal Kulkarni}
647e6ad46Vishal Kulkarni
657e6ad46Vishal Kulkarni/* This function will add additional padding bytes into debug_buffer to make it
667e6ad46Vishal Kulkarni * 4 byte aligned.*/
677e6ad46Vishal Kulkarnistatic void
687e6ad46Vishal Kulkarnialign_debug_buffer(struct cudbg_buffer *dbg_buff,
697e6ad46Vishal Kulkarni		   struct cudbg_entity_hdr *entity_hdr)
707e6ad46Vishal Kulkarni{
717e6ad46Vishal Kulkarni	u8 zero_buf[4] = {0};
727e6ad46Vishal Kulkarni	u8 padding, remain;
737e6ad46Vishal Kulkarni
747e6ad46Vishal Kulkarni	remain = (dbg_buff->offset - entity_hdr->start_offset) % 4;
757e6ad46Vishal Kulkarni	padding = 4 - remain;
767e6ad46Vishal Kulkarni	if (remain) {
777e6ad46Vishal Kulkarni		memcpy(((u8 *) dbg_buff->data) + dbg_buff->offset, &zero_buf,
787e6ad46Vishal Kulkarni		       padding);
797e6ad46Vishal Kulkarni		dbg_buff->offset += padding;
807e6ad46Vishal Kulkarni		entity_hdr->num_pad = padding;
817e6ad46Vishal Kulkarni	}
827e6ad46Vishal Kulkarni
837e6ad46Vishal Kulkarni	entity_hdr->size = dbg_buff->offset - entity_hdr->start_offset;
847e6ad46Vishal Kulkarni}
857e6ad46Vishal Kulkarni
867e6ad46Vishal Kulkarnistatic void
877e6ad46Vishal Kulkarniu32_swap(void *a, void *b, int size)
887e6ad46Vishal Kulkarni{
897e6ad46Vishal Kulkarni        u32 t = *(u32 *)a;
907e6ad46Vishal Kulkarni
917e6ad46Vishal Kulkarni        *(u32 *)a = *(u32 *)b;
927e6ad46Vishal Kulkarni        *(u32 *)b = t;
937e6ad46Vishal Kulkarni}
947e6ad46Vishal Kulkarni
957e6ad46Vishal Kulkarnistatic void
967e6ad46Vishal Kulkarnigeneric_swap(void *a1, void *b1, int size)
977e6ad46Vishal Kulkarni{
987e6ad46Vishal Kulkarni	u8 t;
997e6ad46Vishal Kulkarni	u8 *a = (u8 *)a1;
1007e6ad46Vishal Kulkarni	u8 *b = (u8 *)b1;
1017e6ad46Vishal Kulkarni
1027e6ad46Vishal Kulkarni	do {
1037e6ad46Vishal Kulkarni		t = *a;
1047e6ad46Vishal Kulkarni		*(a++) = *b;
1057e6ad46Vishal Kulkarni		*(b++) = t;
1067e6ad46Vishal Kulkarni	} while (--size > 0);
1077e6ad46Vishal Kulkarni}
1087e6ad46Vishal Kulkarni
1097e6ad46Vishal Kulkarnistatic void
1107e6ad46Vishal Kulkarniqsort(void *base_val, int num, int size,
1117e6ad46Vishal Kulkarni      int (*cmp_func)(const void *, const void *),
1127e6ad46Vishal Kulkarni      void (*swap_func)(void *, void *, int size))
1137e6ad46Vishal Kulkarni{
1147e6ad46Vishal Kulkarni	/* pre-scale counters for performance */
1157e6ad46Vishal Kulkarni	int i = (num / 2 - 1) * size;
1167e6ad46Vishal Kulkarni	int n = num * size;
1177e6ad46Vishal Kulkarni	int c, r;
1187e6ad46Vishal Kulkarni	u8 *base = (u8 *)base_val;
1197e6ad46Vishal Kulkarni
1207e6ad46Vishal Kulkarni	if (!swap_func)
1217e6ad46Vishal Kulkarni		swap_func = (size == 4 ? u32_swap : generic_swap);
1227e6ad46Vishal Kulkarni
1237e6ad46Vishal Kulkarni	/* heapify */
1247e6ad46Vishal Kulkarni	for (; i >= 0; i -= size) {
1257e6ad46Vishal Kulkarni		for (r = i; r * 2 + size < n; r  = c) {
1267e6ad46Vishal Kulkarni			c = r * 2 + size;
1277e6ad46Vishal Kulkarni			if (c < n - size &&
1287e6ad46Vishal Kulkarni					cmp_func(base + c, base + c + size) < 0)
1297e6ad46Vishal Kulkarni				c += size;
1307e6ad46Vishal Kulkarni			if (cmp_func(base + r, base + c) >= 0)
1317e6ad46Vishal Kulkarni				break;
1327e6ad46Vishal Kulkarni			swap_func(base + r, base + c, size);
1337e6ad46Vishal Kulkarni		}
1347e6ad46Vishal Kulkarni	}
1357e6ad46Vishal Kulkarni
1367e6ad46Vishal Kulkarni	/* sort */
1377e6ad46Vishal Kulkarni	for (i = n - size; i > 0; i -= size) {
1387e6ad46Vishal Kulkarni		swap_func(base, base + i, size);
1397e6ad46Vishal Kulkarni		for (r = 0; r * 2 + size < i; r = c) {
1407e6ad46Vishal Kulkarni			c = r * 2 + size;
1417e6ad46Vishal Kulkarni			if (c < i - size &&
1427e6ad46Vishal Kulkarni					cmp_func(base + c, base + c + size) < 0)
1437e6ad46Vishal Kulkarni				c += size;
1447e6ad46Vishal Kulkarni			if (cmp_func(base + r, base + c) >= 0)
1457e6ad46Vishal Kulkarni				break;
1467e6ad46Vishal Kulkarni			swap_func(base + r, base + c, size);
1477e6ad46Vishal Kulkarni		}
1487e6ad46Vishal Kulkarni	}
1497e6ad46Vishal Kulkarni}
1507e6ad46Vishal Kulkarni
1517e6ad46Vishal Kulkarnistatic void
1527e6ad46Vishal Kulkarniread_sge_ctxt(struct cudbg_init *pdbg_init, u32 cid,
1537e6ad46Vishal Kulkarni	      enum ctxt_type ctype, u32 *data)
1547e6ad46Vishal Kulkarni{
1557e6ad46Vishal Kulkarni	struct adapter *padap = pdbg_init->adap;
1567e6ad46Vishal Kulkarni	int rc = -1;
1577e6ad46Vishal Kulkarni
1587e6ad46Vishal Kulkarni	if (is_fw_attached(pdbg_init)) {
1597e6ad46Vishal Kulkarni		rc =begin_synchronized_op(padap->port[0], 1, 1);
1607e6ad46Vishal Kulkarni		if (rc != 0)
1617e6ad46Vishal Kulkarni			goto out;
1627e6ad46Vishal Kulkarni		rc = t4_sge_ctxt_rd(padap, padap->mbox, cid, ctype,
1637e6ad46Vishal Kulkarni				    data);
1647e6ad46Vishal Kulkarni		end_synchronized_op(padap->port[0], 1);
1657e6ad46Vishal Kulkarni	}
1667e6ad46Vishal Kulkarni
1677e6ad46Vishal Kulkarniout:
1687e6ad46Vishal Kulkarni	if (rc)
1697e6ad46Vishal Kulkarni		t4_sge_ctxt_rd_bd(padap, cid, ctype, data);
1707e6ad46Vishal Kulkarni}
1717e6ad46Vishal Kulkarni
1727e6ad46Vishal Kulkarnistatic int
1737e6ad46Vishal Kulkarniget_next_ext_entity_hdr(void *outbuf, u32 *ext_size,
1747e6ad46Vishal Kulkarni			struct cudbg_buffer *dbg_buff,
1757e6ad46Vishal Kulkarni			struct cudbg_entity_hdr **entity_hdr)
1767e6ad46Vishal Kulkarni{
1777e6ad46Vishal Kulkarni	struct cudbg_hdr *cudbg_hdr = (struct cudbg_hdr *)outbuf;
1787e6ad46Vishal Kulkarni	int rc = 0;
1797e6ad46Vishal Kulkarni	u32 ext_offset = cudbg_hdr->data_len;
1807e6ad46Vishal Kulkarni	*ext_size = 0;
1817e6ad46Vishal Kulkarni
1827e6ad46Vishal Kulkarni	if (dbg_buff->size - dbg_buff->offset <=
1837e6ad46Vishal Kulkarni		 sizeof(struct cudbg_entity_hdr)) {
1847e6ad46Vishal Kulkarni		rc = CUDBG_STATUS_BUFFER_SHORT;
1857e6ad46Vishal Kulkarni		goto err;
1867e6ad46Vishal Kulkarni	}
1877e6ad46Vishal Kulkarni
1887e6ad46Vishal Kulkarni	*entity_hdr = (struct cudbg_entity_hdr *)
1897e6ad46Vishal Kulkarni		       ((char *)outbuf + cudbg_hdr->data_len);
1907e6ad46Vishal Kulkarni
1917e6ad46Vishal Kulkarni	/* Find the last extended entity header */
1927e6ad46Vishal Kulkarni	while ((*entity_hdr)->size) {
1937e6ad46Vishal Kulkarni
1947e6ad46Vishal Kulkarni		ext_offset += sizeof(struct cudbg_entity_hdr) +
1957e6ad46Vishal Kulkarni				     (*entity_hdr)->size;
1967e6ad46Vishal Kulkarni
1977e6ad46Vishal Kulkarni		*ext_size += (*entity_hdr)->size +
1987e6ad46Vishal Kulkarni			      sizeof(struct cudbg_entity_hdr);
1997e6ad46Vishal Kulkarni
2007e6ad46Vishal Kulkarni		if (dbg_buff->size - dbg_buff->offset + *ext_size  <=
2017e6ad46Vishal Kulkarni			sizeof(struct cudbg_entity_hdr)) {
2027e6ad46Vishal Kulkarni			rc = CUDBG_STATUS_BUFFER_SHORT;
2037e6ad46Vishal Kulkarni			goto err;
2047e6ad46Vishal Kulkarni		}
2057e6ad46Vishal Kulkarni
2067e6ad46Vishal Kulkarni		if (ext_offset != (*entity_hdr)->next_ext_offset) {
2077e6ad46Vishal Kulkarni			ext_offset -= sizeof(struct cudbg_entity_hdr) +
2087e6ad46Vishal Kulkarni				     (*entity_hdr)->size;
2097e6ad46Vishal Kulkarni			break;
2107e6ad46Vishal Kulkarni		}
2117e6ad46Vishal Kulkarni
2127e6ad46Vishal Kulkarni		(*entity_hdr)->next_ext_offset = *ext_size;
2137e6ad46Vishal Kulkarni
2147e6ad46Vishal Kulkarni		*entity_hdr = (struct cudbg_entity_hdr *)
2157e6ad46Vishal Kulkarni					   ((char *)outbuf +
2167e6ad46Vishal Kulkarni					   ext_offset);
2177e6ad46Vishal Kulkarni	}
2187e6ad46Vishal Kulkarni
2197e6ad46Vishal Kulkarni	/* update the data offset */
2207e6ad46Vishal Kulkarni	dbg_buff->offset = ext_offset;
2217e6ad46Vishal Kulkarnierr:
2227e6ad46Vishal Kulkarni	return rc;
2237e6ad46Vishal Kulkarni}
2247e6ad46Vishal Kulkarni
2257e6ad46Vishal Kulkarnistatic int
2267e6ad46Vishal Kulkarniwr_entity_to_flash(void *handle, struct cudbg_buffer *dbg_buff,
2277e6ad46Vishal Kulkarni		   u32 cur_entity_data_offset,
2287e6ad46Vishal Kulkarni		   u32 cur_entity_size,
2297e6ad46Vishal Kulkarni		   int entity_nu, u32 ext_size)
2307e6ad46Vishal Kulkarni{
2317e6ad46Vishal Kulkarni	struct cudbg_private *priv = handle;
2327e6ad46Vishal Kulkarni	struct cudbg_init *cudbg_init = &priv->dbg_init;
2337e6ad46Vishal Kulkarni	struct cudbg_flash_sec_info *sec_info = &priv->sec_info;
2347e6ad46Vishal Kulkarni	struct adapter *adap = cudbg_init->adap;
2357e6ad46Vishal Kulkarni	u64 timestamp;
2367e6ad46Vishal Kulkarni	u32 cur_entity_hdr_offset = sizeof(struct cudbg_hdr);
2377e6ad46Vishal Kulkarni	u32 remain_flash_size;
2387e6ad46Vishal Kulkarni	u32 flash_data_offset;
2397e6ad46Vishal Kulkarni	u32 data_hdr_size;
2407e6ad46Vishal Kulkarni	int rc = -1;
2417e6ad46Vishal Kulkarni
2427e6ad46Vishal Kulkarni	data_hdr_size = CUDBG_MAX_ENTITY * sizeof(struct cudbg_entity_hdr) +
2437e6ad46Vishal Kulkarni			sizeof(struct cudbg_hdr);
2447e6ad46Vishal Kulkarni
2457e6ad46Vishal Kulkarni	flash_data_offset = (FLASH_CUDBG_NSECS *
2467e6ad46Vishal Kulkarni			     (sizeof(struct cudbg_flash_hdr) +
2477e6ad46Vishal Kulkarni			      data_hdr_size)) +
2487e6ad46Vishal Kulkarni			    (cur_entity_data_offset - data_hdr_size);
2497e6ad46Vishal Kulkarni
2507e6ad46Vishal Kulkarni	if (flash_data_offset > CUDBG_FLASH_SIZE) {
2517e6ad46Vishal Kulkarni		update_skip_size(sec_info, cur_entity_size);
2527e6ad46Vishal Kulkarni		if (cudbg_init->verbose)
2537e6ad46Vishal Kulkarni			cudbg_init->print(adap->dip, CE_NOTE,
2547e6ad46Vishal Kulkarni					  "Large entity skipping...\n");
2557e6ad46Vishal Kulkarni		return rc;
2567e6ad46Vishal Kulkarni	}
2577e6ad46Vishal Kulkarni
2587e6ad46Vishal Kulkarni	remain_flash_size = CUDBG_FLASH_SIZE - flash_data_offset;
2597e6ad46Vishal Kulkarni
2607e6ad46Vishal Kulkarni	if (cur_entity_size > remain_flash_size) {
2617e6ad46Vishal Kulkarni		update_skip_size(sec_info, cur_entity_size);
2627e6ad46Vishal Kulkarni		if (cudbg_init->verbose)
2637e6ad46Vishal Kulkarni			cudbg_init->print(adap->dip, CE_NOTE,
2647e6ad46Vishal Kulkarni					  "Large entity skipping...\n");
2657e6ad46Vishal Kulkarni	} else {
2667e6ad46Vishal Kulkarni		timestamp = 0;
2677e6ad46Vishal Kulkarni
2687e6ad46Vishal Kulkarni		cur_entity_hdr_offset +=
2697e6ad46Vishal Kulkarni			(sizeof(struct cudbg_entity_hdr) *
2707e6ad46Vishal Kulkarni			(entity_nu - 1));
2717e6ad46Vishal Kulkarni
2727e6ad46Vishal Kulkarni		rc = cudbg_write_flash(handle, timestamp, dbg_buff,
2737e6ad46Vishal Kulkarni				       cur_entity_data_offset,
2747e6ad46Vishal Kulkarni				       cur_entity_hdr_offset,
2757e6ad46Vishal Kulkarni				       cur_entity_size,
2767e6ad46Vishal Kulkarni				       ext_size);
2777e6ad46Vishal Kulkarni		if (rc == CUDBG_STATUS_FLASH_FULL && cudbg_init->verbose)
2787e6ad46Vishal Kulkarni			cudbg_init->print(adap->dip, CE_NOTE,
2797e6ad46Vishal Kulkarni					  "\n\tFLASH is full... "
2807e6ad46Vishal Kulkarni					  "can not write in flash more\n\n");
2817e6ad46Vishal Kulkarni	}
2827e6ad46Vishal Kulkarni
2837e6ad46Vishal Kulkarni	return rc;
2847e6ad46Vishal Kulkarni}
2857e6ad46Vishal Kulkarni
2867e6ad46Vishal Kulkarniint
2877e6ad46Vishal Kulkarnicudbg_collect(void *handle, void *outbuf, u32 *outbuf_size)
2887e6ad46Vishal Kulkarni{
2897e6ad46Vishal Kulkarni	struct cudbg_entity_hdr *entity_hdr = NULL;
2907e6ad46Vishal Kulkarni	struct cudbg_entity_hdr *ext_entity_hdr = NULL;
2917e6ad46Vishal Kulkarni	struct cudbg_hdr *cudbg_hdr;
2927e6ad46Vishal Kulkarni	struct cudbg_buffer dbg_buff;
2937e6ad46Vishal Kulkarni	struct cudbg_error cudbg_err = {0};
2947e6ad46Vishal Kulkarni	int large_entity_code;
2957e6ad46Vishal Kulkarni
2967e6ad46Vishal Kulkarni	u8 *dbg_bitmap = ((struct cudbg_private *)handle)->dbg_init.dbg_bitmap;
2977e6ad46Vishal Kulkarni	struct cudbg_init *cudbg_init =
2987e6ad46Vishal Kulkarni		&(((struct cudbg_private *)handle)->dbg_init);
2997e6ad46Vishal Kulkarni	struct adapter *padap = cudbg_init->adap;
3007e6ad46Vishal Kulkarni	u32 total_size, remaining_buf_size;
3017e6ad46Vishal Kulkarni	u32 ext_size = 0;
3027e6ad46Vishal Kulkarni	int index, bit, i, rc = -1;
3037e6ad46Vishal Kulkarni	int all;
3047e6ad46Vishal Kulkarni	bool flag_ext = 0;
3057e6ad46Vishal Kulkarni
3067e6ad46Vishal Kulkarni	reset_skip_entity();
3077e6ad46Vishal Kulkarni
3087e6ad46Vishal Kulkarni	dbg_buff.data = outbuf;
3097e6ad46Vishal Kulkarni	dbg_buff.size = *outbuf_size;
3107e6ad46Vishal Kulkarni	dbg_buff.offset = 0;
3117e6ad46Vishal Kulkarni
3127e6ad46Vishal Kulkarni	cudbg_hdr = (struct cudbg_hdr *)dbg_buff.data;
3137e6ad46Vishal Kulkarni	cudbg_hdr->signature = CUDBG_SIGNATURE;
3147e6ad46Vishal Kulkarni	cudbg_hdr->hdr_len = sizeof(struct cudbg_hdr);
3157e6ad46Vishal Kulkarni	cudbg_hdr->major_ver = CUDBG_MAJOR_VERSION;
3167e6ad46Vishal Kulkarni	cudbg_hdr->minor_ver = CUDBG_MINOR_VERSION;
3177e6ad46Vishal Kulkarni	cudbg_hdr->max_entities = CUDBG_MAX_ENTITY;
3187e6ad46Vishal Kulkarni	cudbg_hdr->chip_ver = padap->params.chip;
3197e6ad46Vishal Kulkarni
3207e6ad46Vishal Kulkarni	if (cudbg_hdr->data_len)
3217e6ad46Vishal Kulkarni		flag_ext = 1;
3227e6ad46Vishal Kulkarni
3237e6ad46Vishal Kulkarni	if (sizeof(struct cudbg_entity_hdr) * CUDBG_MAX_ENTITY >
3247e6ad46Vishal Kulkarni	    dbg_buff.size) {
3257e6ad46Vishal Kulkarni		rc = CUDBG_STATUS_SMALL_BUFF;
3267e6ad46Vishal Kulkarni		total_size = cudbg_hdr->hdr_len;
3277e6ad46Vishal Kulkarni		goto err;
3287e6ad46Vishal Kulkarni	}
3297e6ad46Vishal Kulkarni
3307e6ad46Vishal Kulkarni	/* If ext flag is set then move the offset to the end of the buf
3317e6ad46Vishal Kulkarni	 * so that we can add ext entities
3327e6ad46Vishal Kulkarni	 */
3337e6ad46Vishal Kulkarni	if (flag_ext) {
3347e6ad46Vishal Kulkarni		ext_entity_hdr = (struct cudbg_entity_hdr *)
3357e6ad46Vishal Kulkarni			      ((char *)outbuf + cudbg_hdr->hdr_len +
3367e6ad46Vishal Kulkarni			      (sizeof(struct cudbg_entity_hdr) *
3377e6ad46Vishal Kulkarni			      (CUDBG_EXT_ENTITY - 1)));
3387e6ad46Vishal Kulkarni		ext_entity_hdr->start_offset = cudbg_hdr->data_len;
3397e6ad46Vishal Kulkarni		ext_entity_hdr->entity_type = CUDBG_EXT_ENTITY;
3407e6ad46Vishal Kulkarni		ext_entity_hdr->size = 0;
3417e6ad46Vishal Kulkarni		dbg_buff.offset = cudbg_hdr->data_len;
3427e6ad46Vishal Kulkarni	} else {
3437e6ad46Vishal Kulkarni		dbg_buff.offset += cudbg_hdr->hdr_len; /* move 24 bytes*/
3447e6ad46Vishal Kulkarni		dbg_buff.offset += CUDBG_MAX_ENTITY *
3457e6ad46Vishal Kulkarni					sizeof(struct cudbg_entity_hdr);
3467e6ad46Vishal Kulkarni	}
3477e6ad46Vishal Kulkarni
3487e6ad46Vishal Kulkarni	total_size = dbg_buff.offset;
3497e6ad46Vishal Kulkarni	all = dbg_bitmap[0] & (1 << CUDBG_ALL);
3507e6ad46Vishal Kulkarni
3517e6ad46Vishal Kulkarni	for (i = 1; i < CUDBG_MAX_ENTITY; i++) {
3527e6ad46Vishal Kulkarni		index = i / 8;
3537e6ad46Vishal Kulkarni		bit = i % 8;
3547e6ad46Vishal Kulkarni
3557e6ad46Vishal Kulkarni		if (entity_list[i].bit == CUDBG_EXT_ENTITY)
3567e6ad46Vishal Kulkarni			continue;
3577e6ad46Vishal Kulkarni
3587e6ad46Vishal Kulkarni		if (all || (dbg_bitmap[index] & (1 << bit))) {
3597e6ad46Vishal Kulkarni
3607e6ad46Vishal Kulkarni			if (!flag_ext) {
3617e6ad46Vishal Kulkarni				rc = get_entity_hdr(outbuf, i, dbg_buff.size,
3627e6ad46Vishal Kulkarni						    &entity_hdr);
3637e6ad46Vishal Kulkarni				if (rc)
3647e6ad46Vishal Kulkarni					cudbg_hdr->hdr_flags = rc;
3657e6ad46Vishal Kulkarni			} else {
3667e6ad46Vishal Kulkarni				rc = get_next_ext_entity_hdr(outbuf, &ext_size,
3677e6ad46Vishal Kulkarni							     &dbg_buff,
3687e6ad46Vishal Kulkarni							     &entity_hdr);
3697e6ad46Vishal Kulkarni				if (rc)
3707e6ad46Vishal Kulkarni					goto err;
3717e6ad46Vishal Kulkarni
3727e6ad46Vishal Kulkarni				/* move the offset after the ext header */
3737e6ad46Vishal Kulkarni				dbg_buff.offset +=
3747e6ad46Vishal Kulkarni					sizeof(struct cudbg_entity_hdr);
3757e6ad46Vishal Kulkarni			}
3767e6ad46Vishal Kulkarni
3777e6ad46Vishal Kulkarni			entity_hdr->entity_type = i;
3787e6ad46Vishal Kulkarni			entity_hdr->start_offset = dbg_buff.offset;
3797e6ad46Vishal Kulkarni			/* process each entity by calling process_entity fp */
3807e6ad46Vishal Kulkarni			remaining_buf_size = dbg_buff.size - dbg_buff.offset;
3817e6ad46Vishal Kulkarni
3827e6ad46Vishal Kulkarni			if ((remaining_buf_size <= BUFFER_WARN_LIMIT) &&
3837e6ad46Vishal Kulkarni			    is_large_entity(i)) {
3847e6ad46Vishal Kulkarni				if (cudbg_init->verbose)
3857e6ad46Vishal Kulkarni					cudbg_init->print(padap->dip, CE_NOTE,
3867e6ad46Vishal Kulkarni							  "Skipping %s\n",
3877e6ad46Vishal Kulkarni					    entity_list[i].name);
3887e6ad46Vishal Kulkarni				skip_entity(i);
3897e6ad46Vishal Kulkarni				continue;
3907e6ad46Vishal Kulkarni			} else {
3917e6ad46Vishal Kulkarni
3927e6ad46Vishal Kulkarni				/* If fw_attach is 0, then skip entities which
3937e6ad46Vishal Kulkarni				 * communicates with firmware
3947e6ad46Vishal Kulkarni				 */
3957e6ad46Vishal Kulkarni
3967e6ad46Vishal Kulkarni				if (!is_fw_attached(cudbg_init) &&
3977e6ad46Vishal Kulkarni				    (entity_list[i].flag &
3987e6ad46Vishal Kulkarni				    (1 << ENTITY_FLAG_FW_NO_ATTACH))) {
3997e6ad46Vishal Kulkarni					if (cudbg_init->verbose)
4007e6ad46Vishal Kulkarni						cudbg_init->print(padap->dip, CE_NOTE,
4017e6ad46Vishal Kulkarni							  "Skipping %s entity,"\
4027e6ad46Vishal Kulkarni							  "because fw_attach "\
4037e6ad46Vishal Kulkarni							  "is 0\n",
4047e6ad46Vishal Kulkarni							  entity_list[i].name);
4057e6ad46Vishal Kulkarni					continue;
4067e6ad46Vishal Kulkarni				}
4077e6ad46Vishal Kulkarni
4087e6ad46Vishal Kulkarni				if (cudbg_init->verbose)
4097e6ad46Vishal Kulkarni					cudbg_init->print(padap->dip, CE_NOTE,
4107e6ad46Vishal Kulkarni							  "collecting debug entity: "\
4117e6ad46Vishal Kulkarni						  "%s\n", entity_list[i].name);
4127e6ad46Vishal Kulkarni				memset(&cudbg_err, 0,
4137e6ad46Vishal Kulkarni				       sizeof(struct cudbg_error));
4147e6ad46Vishal Kulkarni				rc = process_entity[i-1](cudbg_init, &dbg_buff,
4157e6ad46Vishal Kulkarni							 &cudbg_err);
4167e6ad46Vishal Kulkarni			}
4177e6ad46Vishal Kulkarni
4187e6ad46Vishal Kulkarni			if (rc) {
4197e6ad46Vishal Kulkarni				entity_hdr->size = 0;
4207e6ad46Vishal Kulkarni				dbg_buff.offset = entity_hdr->start_offset;
4217e6ad46Vishal Kulkarni			} else
4227e6ad46Vishal Kulkarni				align_debug_buffer(&dbg_buff, entity_hdr);
4237e6ad46Vishal Kulkarni
4247e6ad46Vishal Kulkarni			if (cudbg_err.sys_err)
4257e6ad46Vishal Kulkarni				rc = CUDBG_SYSTEM_ERROR;
4267e6ad46Vishal Kulkarni
4277e6ad46Vishal Kulkarni			entity_hdr->hdr_flags =  rc;
4287e6ad46Vishal Kulkarni			entity_hdr->sys_err = cudbg_err.sys_err;
4297e6ad46Vishal Kulkarni			entity_hdr->sys_warn =	cudbg_err.sys_warn;
4307e6ad46Vishal Kulkarni
4317e6ad46Vishal Kulkarni			/* We don't want to include ext entity size in global
4327e6ad46Vishal Kulkarni			 * header
4337e6ad46Vishal Kulkarni			 */
4347e6ad46Vishal Kulkarni			if (!flag_ext)
4357e6ad46Vishal Kulkarni				total_size += entity_hdr->size;
4367e6ad46Vishal Kulkarni
4377e6ad46Vishal Kulkarni			cudbg_hdr->data_len = total_size;
4387e6ad46Vishal Kulkarni			*outbuf_size = total_size;
4397e6ad46Vishal Kulkarni
4407e6ad46Vishal Kulkarni			/* consider the size of the ext entity header and data
4417e6ad46Vishal Kulkarni			 * also
4427e6ad46Vishal Kulkarni			 */
4437e6ad46Vishal Kulkarni			if (flag_ext) {
4447e6ad46Vishal Kulkarni				ext_size += (sizeof(struct cudbg_entity_hdr) +
4457e6ad46Vishal Kulkarni					     entity_hdr->size);
4467e6ad46Vishal Kulkarni				entity_hdr->start_offset -= cudbg_hdr->data_len;
4477e6ad46Vishal Kulkarni				ext_entity_hdr->size = ext_size;
4487e6ad46Vishal Kulkarni				entity_hdr->next_ext_offset = ext_size;
4497e6ad46Vishal Kulkarni				entity_hdr->flag |= CUDBG_EXT_DATA_VALID;
4507e6ad46Vishal Kulkarni			}
4517e6ad46Vishal Kulkarni
4527e6ad46Vishal Kulkarni			if (cudbg_init->use_flash) {
4537e6ad46Vishal Kulkarni				if (flag_ext) {
4547e6ad46Vishal Kulkarni					wr_entity_to_flash(handle,
4557e6ad46Vishal Kulkarni							   &dbg_buff,
4567e6ad46Vishal Kulkarni							   ext_entity_hdr->
4577e6ad46Vishal Kulkarni							   start_offset,
4587e6ad46Vishal Kulkarni							   entity_hdr->
4597e6ad46Vishal Kulkarni							   size,
4607e6ad46Vishal Kulkarni							   CUDBG_EXT_ENTITY,
4617e6ad46Vishal Kulkarni							   ext_size);
4627e6ad46Vishal Kulkarni				}
4637e6ad46Vishal Kulkarni				else
4647e6ad46Vishal Kulkarni					wr_entity_to_flash(handle,
4657e6ad46Vishal Kulkarni							   &dbg_buff,
4667e6ad46Vishal Kulkarni							   entity_hdr->\
4677e6ad46Vishal Kulkarni							   start_offset,
4687e6ad46Vishal Kulkarni							   entity_hdr->size,
4697e6ad46Vishal Kulkarni							   i, ext_size);
4707e6ad46Vishal Kulkarni			}
4717e6ad46Vishal Kulkarni		}
4727e6ad46Vishal Kulkarni	}
4737e6ad46Vishal Kulkarni
4747e6ad46Vishal Kulkarni	for (i = 0; i < sizeof(large_entity_list) / sizeof(struct large_entity);
4757e6ad46Vishal Kulkarni	     i++) {
4767e6ad46Vishal Kulkarni		large_entity_code = large_entity_list[i].entity_code;
4777e6ad46Vishal Kulkarni		if (large_entity_list[i].skip_flag) {
4787e6ad46Vishal Kulkarni			if (!flag_ext) {
4797e6ad46Vishal Kulkarni				rc = get_entity_hdr(outbuf, large_entity_code,
4807e6ad46Vishal Kulkarni						    dbg_buff.size, &entity_hdr);
4817e6ad46Vishal Kulkarni				if (rc)
4827e6ad46Vishal Kulkarni					cudbg_hdr->hdr_flags = rc;
4837e6ad46Vishal Kulkarni			} else {
4847e6ad46Vishal Kulkarni				rc = get_next_ext_entity_hdr(outbuf, &ext_size,
4857e6ad46Vishal Kulkarni							     &dbg_buff,
4867e6ad46Vishal Kulkarni							     &entity_hdr);
4877e6ad46Vishal Kulkarni				if (rc)
4887e6ad46Vishal Kulkarni					goto err;
4897e6ad46Vishal Kulkarni
4907e6ad46Vishal Kulkarni				dbg_buff.offset +=
4917e6ad46Vishal Kulkarni					sizeof(struct cudbg_entity_hdr);
4927e6ad46Vishal Kulkarni			}
4937e6ad46Vishal Kulkarni
4947e6ad46Vishal Kulkarni			/* If fw_attach is 0, then skip entities which
4957e6ad46Vishal Kulkarni			 * communicates with firmware
4967e6ad46Vishal Kulkarni			 */
4977e6ad46Vishal Kulkarni			if (!is_fw_attached(cudbg_init) &&
4987e6ad46Vishal Kulkarni			    (entity_list[large_entity_code].flag &
4997e6ad46Vishal Kulkarni			    (1 << ENTITY_FLAG_FW_NO_ATTACH))) {
5007e6ad46Vishal Kulkarni				if (cudbg_init->verbose)
5017e6ad46Vishal Kulkarni					cudbg_init->print(padap->dip, CE_NOTE,
5027e6ad46Vishal Kulkarni						  "Skipping %s entity,"\
5037e6ad46Vishal Kulkarni						  "because fw_attach "\
5047e6ad46Vishal Kulkarni						  "is 0\n",
5057e6ad46Vishal Kulkarni						  entity_list[large_entity_code]
5067e6ad46Vishal Kulkarni						  .name);
5077e6ad46Vishal Kulkarni				continue;
5087e6ad46Vishal Kulkarni			}
5097e6ad46Vishal Kulkarni
5107e6ad46Vishal Kulkarni			entity_hdr->entity_type = large_entity_code;
5117e6ad46Vishal Kulkarni			entity_hdr->start_offset = dbg_buff.offset;
5127e6ad46Vishal Kulkarni			if (cudbg_init->verbose)
5137e6ad46Vishal Kulkarni				cudbg_init->print(padap->dip, CE_NOTE,
5147e6ad46Vishal Kulkarni					  "Re-trying debug entity: %s\n",
5157e6ad46Vishal Kulkarni					  entity_list[large_entity_code].name);
5167e6ad46Vishal Kulkarni
5177e6ad46Vishal Kulkarni			memset(&cudbg_err, 0, sizeof(struct cudbg_error));
5187e6ad46Vishal Kulkarni			rc = process_entity[large_entity_code - 1](cudbg_init,
5197e6ad46Vishal Kulkarni								   &dbg_buff,
5207e6ad46Vishal Kulkarni								   &cudbg_err);
5217e6ad46Vishal Kulkarni			if (rc) {
5227e6ad46Vishal Kulkarni				entity_hdr->size = 0;
5237e6ad46Vishal Kulkarni				dbg_buff.offset = entity_hdr->start_offset;
5247e6ad46Vishal Kulkarni			} else
5257e6ad46Vishal Kulkarni				align_debug_buffer(&dbg_buff, entity_hdr);
5267e6ad46Vishal Kulkarni
5277e6ad46Vishal Kulkarni			if (cudbg_err.sys_err)
5287e6ad46Vishal Kulkarni				rc = CUDBG_SYSTEM_ERROR;
5297e6ad46Vishal Kulkarni
5307e6ad46Vishal Kulkarni			entity_hdr->hdr_flags = rc;
5317e6ad46Vishal Kulkarni			entity_hdr->sys_err = cudbg_err.sys_err;
5327e6ad46Vishal Kulkarni			entity_hdr->sys_warn =	cudbg_err.sys_warn;
5337e6ad46Vishal Kulkarni
5347e6ad46Vishal Kulkarni			/* We don't want to include ext entity size in global
5357e6ad46Vishal Kulkarni			 * header
5367e6ad46Vishal Kulkarni			 */
5377e6ad46Vishal Kulkarni			if (!flag_ext)
5387e6ad46Vishal Kulkarni				total_size += entity_hdr->size;
5397e6ad46Vishal Kulkarni
5407e6ad46Vishal Kulkarni			cudbg_hdr->data_len = total_size;
5417e6ad46Vishal Kulkarni			*outbuf_size = total_size;
5427e6ad46Vishal Kulkarni
5437e6ad46Vishal Kulkarni			/* consider the size of the ext entity header and
5447e6ad46Vishal Kulkarni			 * data also
5457e6ad46Vishal Kulkarni			 */
5467e6ad46Vishal Kulkarni			if (flag_ext) {
5477e6ad46Vishal Kulkarni				ext_size += (sizeof(struct cudbg_entity_hdr) +
5487e6ad46Vishal Kulkarni						   entity_hdr->size);
5497e6ad46Vishal Kulkarni				entity_hdr->start_offset -=
5507e6ad46Vishal Kulkarni							cudbg_hdr->data_len;
5517e6ad46Vishal Kulkarni				ext_entity_hdr->size = ext_size;
5527e6ad46Vishal Kulkarni				entity_hdr->flag |= CUDBG_EXT_DATA_VALID;
5537e6ad46Vishal Kulkarni			}
5547e6ad46Vishal Kulkarni
5557e6ad46Vishal Kulkarni			if (cudbg_init->use_flash) {
5567e6ad46Vishal Kulkarni				if (flag_ext)
5577e6ad46Vishal Kulkarni					wr_entity_to_flash(handle,
5587e6ad46Vishal Kulkarni							   &dbg_buff,
5597e6ad46Vishal Kulkarni							   ext_entity_hdr->
5607e6ad46Vishal Kulkarni							   start_offset,
5617e6ad46Vishal Kulkarni							   entity_hdr->size,
5627e6ad46Vishal Kulkarni							   CUDBG_EXT_ENTITY,
5637e6ad46Vishal Kulkarni							   ext_size);
5647e6ad46Vishal Kulkarni				else
5657e6ad46Vishal Kulkarni					wr_entity_to_flash(handle,
5667e6ad46Vishal Kulkarni							   &dbg_buff,
5677e6ad46Vishal Kulkarni							   entity_hdr->
5687e6ad46Vishal Kulkarni							   start_offset,
5697e6ad46Vishal Kulkarni							   entity_hdr->
5707e6ad46Vishal Kulkarni							   size,
5717e6ad46Vishal Kulkarni							   large_entity_list[i].
5727e6ad46Vishal Kulkarni							   entity_code,
5737e6ad46Vishal Kulkarni							   ext_size);
5747e6ad46Vishal Kulkarni			}
5757e6ad46Vishal Kulkarni		}
5767e6ad46Vishal Kulkarni	}
5777e6ad46Vishal Kulkarni
5787e6ad46Vishal Kulkarni	cudbg_hdr->data_len = total_size;
5797e6ad46Vishal Kulkarni	*outbuf_size = total_size;
5807e6ad46Vishal Kulkarni
5817e6ad46Vishal Kulkarni	if (flag_ext)
5827e6ad46Vishal Kulkarni		*outbuf_size += ext_size;
5837e6ad46Vishal Kulkarni
5847e6ad46Vishal Kulkarni	return 0;
5857e6ad46Vishal Kulkarnierr:
5867e6ad46Vishal Kulkarni	return rc;
5877e6ad46Vishal Kulkarni}
5887e6ad46Vishal Kulkarni
5897e6ad46Vishal Kulkarnivoid
5907e6ad46Vishal Kulkarnireset_skip_entity(void)
5917e6ad46Vishal Kulkarni{
5927e6ad46Vishal Kulkarni	int i;
5937e6ad46Vishal Kulkarni
5947e6ad46Vishal Kulkarni	for (i = 0; i < ARRAY_SIZE(large_entity_list); i++)
5957e6ad46Vishal Kulkarni		large_entity_list[i].skip_flag = 0;
5967e6ad46Vishal Kulkarni}
5977e6ad46Vishal Kulkarni
5987e6ad46Vishal Kulkarnivoid
5997e6ad46Vishal Kulkarniskip_entity(int entity_code)
6007e6ad46Vishal Kulkarni{
6017e6ad46Vishal Kulkarni	int i;
6027e6ad46Vishal Kulkarni	for (i = 0; i < sizeof(large_entity_list) / sizeof(struct large_entity);
6037e6ad46Vishal Kulkarni	     i++) {
6047e6ad46Vishal Kulkarni		if (large_entity_list[i].entity_code == entity_code)
6057e6ad46Vishal Kulkarni			large_entity_list[i].skip_flag = 1;
6067e6ad46Vishal Kulkarni	}
6077e6ad46Vishal Kulkarni}
6087e6ad46Vishal Kulkarni
6097e6ad46Vishal Kulkarniint
6107e6ad46Vishal Kulkarniis_large_entity(int entity_code)
6117e6ad46Vishal Kulkarni{
6127e6ad46Vishal Kulkarni	int i;
6137e6ad46Vishal Kulkarni
6147e6ad46Vishal Kulkarni	for (i = 0; i < sizeof(large_entity_list) / sizeof(struct large_entity);
6157e6ad46Vishal Kulkarni	     i++) {
6167e6ad46Vishal Kulkarni		if (large_entity_list[i].entity_code == entity_code)
6177e6ad46Vishal Kulkarni			return 1;
6187e6ad46Vishal Kulkarni	}
6197e6ad46Vishal Kulkarni	return 0;
6207e6ad46Vishal Kulkarni}
6217e6ad46Vishal Kulkarni
6227e6ad46Vishal Kulkarniint
6237e6ad46Vishal Kulkarniget_entity_hdr(void *outbuf, int i, u32 size,
6247e6ad46Vishal Kulkarni	       struct cudbg_entity_hdr **entity_hdr)
6257e6ad46Vishal Kulkarni{
6267e6ad46Vishal Kulkarni	int rc = 0;
6277e6ad46Vishal Kulkarni	struct cudbg_hdr *cudbg_hdr = (struct cudbg_hdr *)outbuf;
6287e6ad46Vishal Kulkarni
6297e6ad46Vishal Kulkarni	if (cudbg_hdr->hdr_len + (sizeof(struct cudbg_entity_hdr)*i) > size)
6307e6ad46Vishal Kulkarni		return CUDBG_STATUS_SMALL_BUFF;
6317e6ad46Vishal Kulkarni
6327e6ad46Vishal Kulkarni	*entity_hdr = (struct cudbg_entity_hdr *)
6337e6ad46Vishal Kulkarni		      ((char *)outbuf+cudbg_hdr->hdr_len +
6347e6ad46Vishal Kulkarni		       (sizeof(struct cudbg_entity_hdr)*(i-1)));
6357e6ad46Vishal Kulkarni	return rc;
6367e6ad46Vishal Kulkarni}
6377e6ad46Vishal Kulkarni
6387e6ad46Vishal Kulkarnistatic int
6397e6ad46Vishal Kulkarnicollect_rss(struct cudbg_init *pdbg_init,
6407e6ad46Vishal Kulkarni	    struct cudbg_buffer *dbg_buff,
6417e6ad46Vishal Kulkarni	    struct cudbg_error *cudbg_err)
6427e6ad46Vishal Kulkarni{
6437e6ad46Vishal Kulkarni	struct adapter *padap = pdbg_init->adap;
6447e6ad46Vishal Kulkarni	struct cudbg_buffer scratch_buff;
6457e6ad46Vishal Kulkarni	u32 size;
6467e6ad46Vishal Kulkarni	int rc = 0;
6477e6ad46Vishal Kulkarni
6487e6ad46Vishal Kulkarni	size = RSS_NENTRIES  * sizeof(u16);
6497e6ad46Vishal Kulkarni	rc = get_scratch_buff(dbg_buff, size, &scratch_buff);
6507e6ad46Vishal Kulkarni	if (rc)
6517e6ad46Vishal Kulkarni		goto err;
6527e6ad46Vishal Kulkarni
6537e6ad46Vishal Kulkarni	rc = t4_read_rss(padap, (u16 *)scratch_buff.data);
6547e6ad46Vishal Kulkarni	if (rc) {
6557e6ad46Vishal Kulkarni		if (pdbg_init->verbose)
6567e6ad46Vishal Kulkarni			pdbg_init->print(padap->dip, CE_NOTE,
6577e6ad46Vishal Kulkarni					 "%s(), t4_read_rss failed!, rc: %d\n",
6587e6ad46Vishal Kulkarni				 __func__, rc);
6597e6ad46Vishal Kulkarni		cudbg_err->sys_err = rc;
6607e6ad46Vishal Kulkarni		goto err1;
6617e6ad46Vishal Kulkarni	}
6627e6ad46Vishal Kulkarni
6637e6ad46Vishal Kulkarni	rc = write_compression_hdr(&scratch_buff, dbg_buff);
6647e6ad46Vishal Kulkarni	if (rc)
6657e6ad46Vishal Kulkarni		goto err1;
6667e6ad46Vishal Kulkarni
6677e6ad46Vishal Kulkarni	rc = compress_buff(&scratch_buff, dbg_buff);
6687e6ad46Vishal Kulkarni
6697e6ad46Vishal Kulkarnierr1:
6707e6ad46Vishal Kulkarni	release_scratch_buff(&scratch_buff, dbg_buff);
6717e6ad46Vishal Kulkarnierr:
6727e6ad46Vishal Kulkarni	return rc;
6737e6ad46Vishal Kulkarni}
6747e6ad46Vishal Kulkarni
6757e6ad46Vishal Kulkarnistatic int
6767e6ad46Vishal Kulkarnicollect_sw_state(struct cudbg_init *pdbg_init,
6777e6ad46Vishal Kulkarni		 struct cudbg_buffer *dbg_buff,
6787e6ad46Vishal Kulkarni		 struct cudbg_error *cudbg_err)
6797e6ad46Vishal Kulkarni{
6807e6ad46Vishal Kulkarni	struct adapter *padap = pdbg_init->adap;
6817e6ad46Vishal Kulkarni	struct cudbg_buffer scratch_buff;
6827e6ad46Vishal Kulkarni	struct sw_state *swstate;
6837e6ad46Vishal Kulkarni	u32 size;
6847e6ad46Vishal Kulkarni	int rc = 0;
6857e6ad46Vishal Kulkarni
6867e6ad46Vishal Kulkarni	size = sizeof(struct sw_state);
6877e6ad46Vishal Kulkarni
6887e6ad46Vishal Kulkarni	rc = get_scratch_buff(dbg_buff, size, &scratch_buff);
6897e6ad46Vishal Kulkarni	if (rc)
6907e6ad46Vishal Kulkarni		goto err;
6917e6ad46Vishal Kulkarni
6927e6ad46Vishal Kulkarni	swstate = (struct sw_state *) scratch_buff.data;
6937e6ad46Vishal Kulkarni
6947e6ad46Vishal Kulkarni	swstate->fw_state = t4_read_reg(padap, A_PCIE_FW);
6957e6ad46Vishal Kulkarni	snprintf((char *)swstate->caller_string, sizeof(swstate->caller_string), "%s",
6967e6ad46Vishal Kulkarni	    "Illumos");
6977e6ad46Vishal Kulkarni	swstate->os_type = 0;
6987e6ad46Vishal Kulkarni
6997e6ad46Vishal Kulkarni	rc = write_compression_hdr(&scratch_buff, dbg_buff);
7007e6ad46Vishal Kulkarni	if (rc)
7017e6ad46Vishal Kulkarni		goto err1;
7027e6ad46Vishal Kulkarni
7037e6ad46Vishal Kulkarni	rc = compress_buff(&scratch_buff, dbg_buff);
7047e6ad46Vishal Kulkarni
7057e6ad46Vishal Kulkarnierr1:
7067e6ad46Vishal Kulkarni	release_scratch_buff(&scratch_buff, dbg_buff);
7077e6ad46Vishal Kulkarnierr:
7087e6ad46Vishal Kulkarni	return rc;
7097e6ad46Vishal Kulkarni}
7107e6ad46Vishal Kulkarni
7117e6ad46Vishal Kulkarnistatic int
7127e6ad46Vishal Kulkarnicollect_ddp_stats(struct cudbg_init *pdbg_init,
7137e6ad46Vishal Kulkarni		  struct cudbg_buffer *dbg_buff,
7147e6ad46Vishal Kulkarni		  struct cudbg_error *cudbg_err)
7157e6ad46Vishal Kulkarni{
7167e6ad46Vishal Kulkarni	struct adapter *padap = pdbg_init->adap;
7177e6ad46Vishal Kulkarni	struct cudbg_buffer scratch_buff;
7187e6ad46Vishal Kulkarni	struct tp_usm_stats  *tp_usm_stats_buff;
7197e6ad46Vishal Kulkarni	u32 size;
7207e6ad46Vishal Kulkarni	int rc = 0;
7217e6ad46Vishal Kulkarni
7227e6ad46Vishal Kulkarni	size = sizeof(struct tp_usm_stats);
7237e6ad46Vishal Kulkarni
7247e6ad46Vishal Kulkarni	rc = get_scratch_buff(dbg_buff, size, &scratch_buff);
7257e6ad46Vishal Kulkarni	if (rc)
7267e6ad46Vishal Kulkarni		goto err;
7277e6ad46Vishal Kulkarni
7287e6ad46Vishal Kulkarni	tp_usm_stats_buff = (struct tp_usm_stats *) scratch_buff.data;
7297e6ad46Vishal Kulkarni
7307e6ad46Vishal Kulkarni	/* spin_lock(&padap->stats_lock);	TODO*/
7317e6ad46Vishal Kulkarni	t4_get_usm_stats(padap, tp_usm_stats_buff, 1);
7327e6ad46Vishal Kulkarni	/* spin_unlock(&padap->stats_lock);	TODO*/
7337e6ad46Vishal Kulkarni
7347e6ad46Vishal Kulkarni	rc = write_compression_hdr(&scratch_buff, dbg_buff);
7357e6ad46Vishal Kulkarni	if (rc)
7367e6ad46Vishal Kulkarni		goto err1;
7377e6ad46Vishal Kulkarni
7387e6ad46Vishal Kulkarni	rc = compress_buff(&scratch_buff, dbg_buff);
7397e6ad46Vishal Kulkarni
7407e6ad46Vishal Kulkarnierr1:
7417e6ad46Vishal Kulkarni	release_scratch_buff(&scratch_buff, dbg_buff);
7427e6ad46Vishal Kulkarnierr:
7437e6ad46Vishal Kulkarni	return rc;
7447e6ad46Vishal Kulkarni}
7457e6ad46Vishal Kulkarni
7467e6ad46Vishal Kulkarnistatic int
7477e6ad46Vishal Kulkarnicollect_ulptx_la(struct cudbg_init *pdbg_init,
7487e6ad46Vishal Kulkarni		 struct cudbg_buffer *dbg_buff,
7497e6ad46Vishal Kulkarni		 struct cudbg_error *cudbg_err)
7507e6ad46Vishal Kulkarni{
7517e6ad46Vishal Kulkarni	struct adapter *padap = pdbg_init->adap;
7527e6ad46Vishal Kulkarni	struct cudbg_buffer scratch_buff;
7537e6ad46Vishal Kulkarni	struct struct_ulptx_la *ulptx_la_buff;
7547e6ad46Vishal Kulkarni	u32 size, i, j;
7557e6ad46Vishal Kulkarni	int rc = 0;
7567e6ad46Vishal Kulkarni
7577e6ad46Vishal Kulkarni	size = sizeof(struct struct_ulptx_la);
7587e6ad46Vishal Kulkarni
7597e6ad46Vishal Kulkarni	rc = get_scratch_buff(dbg_buff, size, &scratch_buff);
7607e6ad46Vishal Kulkarni	if (rc)
7617e6ad46Vishal Kulkarni		goto err;
7627e6ad46Vishal Kulkarni
7637e6ad46Vishal Kulkarni	ulptx_la_buff = (struct struct_ulptx_la *) scratch_buff.data;
7647e6ad46Vishal Kulkarni
7657e6ad46Vishal Kulkarni	for (i = 0; i < CUDBG_NUM_ULPTX; i++) {
7667e6ad46Vishal Kulkarni		ulptx_la_buff->rdptr[i] = t4_read_reg(padap,
7677e6ad46Vishal Kulkarni						      A_ULP_TX_LA_RDPTR_0 +
7687e6ad46Vishal Kulkarni						      0x10 * i);
7697e6ad46Vishal Kulkarni		ulptx_la_buff->wrptr[i] = t4_read_reg(padap,
7707e6ad46Vishal Kulkarni						      A_ULP_TX_LA_WRPTR_0 +
7717e6ad46Vishal Kulkarni						      0x10 * i);
7727e6ad46Vishal Kulkarni		ulptx_la_buff->rddata[i] = t4_read_reg(padap,
7737e6ad46Vishal Kulkarni						       A_ULP_TX_LA_RDDATA_0 +
7747e6ad46Vishal Kulkarni						       0x10 * i);
7757e6ad46Vishal Kulkarni		for (j = 0; j < CUDBG_NUM_ULPTX_READ; j++) {
7767e6ad46Vishal Kulkarni			ulptx_la_buff->rd_data[i][j] =
7777e6ad46Vishal Kulkarni				t4_read_reg(padap,
7787e6ad46Vishal Kulkarni					    A_ULP_TX_LA_RDDATA_0 + 0x10 * i);
7797e6ad46Vishal Kulkarni		}
7807e6ad46Vishal Kulkarni	}
7817e6ad46Vishal Kulkarni
7827e6ad46Vishal Kulkarni	rc = write_compression_hdr(&scratch_buff, dbg_buff);
7837e6ad46Vishal Kulkarni	if (rc)
7847e6ad46Vishal Kulkarni		goto err1;
7857e6ad46Vishal Kulkarni
7867e6ad46Vishal Kulkarni	rc = compress_buff(&scratch_buff, dbg_buff);
7877e6ad46Vishal Kulkarni
7887e6ad46Vishal Kulkarnierr1:
7897e6ad46Vishal Kulkarni	release_scratch_buff(&scratch_buff, dbg_buff);
7907e6ad46Vishal Kulkarnierr:
7917e6ad46Vishal Kulkarni	return rc;
7927e6ad46Vishal Kulkarni
7937e6ad46Vishal Kulkarni}
7947e6ad46Vishal Kulkarni
7957e6ad46Vishal Kulkarnistatic int
7967e6ad46Vishal Kulkarnicollect_ulprx_la(struct cudbg_init *pdbg_init,
7977e6ad46Vishal Kulkarni		 struct cudbg_buffer *dbg_buff,
7987e6ad46Vishal Kulkarni		 struct cudbg_error *cudbg_err)
7997e6ad46Vishal Kulkarni{
8007e6ad46Vishal Kulkarni	struct adapter *padap = pdbg_init->adap;
8017e6ad46Vishal Kulkarni	struct cudbg_buffer scratch_buff;
8027e6ad46Vishal Kulkarni	struct struct_ulprx_la *ulprx_la_buff;
8037e6ad46Vishal Kulkarni	u32 size;
8047e6ad46Vishal Kulkarni	int rc = 0;
8057e6ad46Vishal Kulkarni
8067e6ad46Vishal Kulkarni	size = sizeof(struct struct_ulprx_la);
8077e6ad46Vishal Kulkarni
8087e6ad46Vishal Kulkarni	rc = get_scratch_buff(dbg_buff, size, &scratch_buff);
8097e6ad46Vishal Kulkarni	if (rc)
8107e6ad46Vishal Kulkarni		goto err;
8117e6ad46Vishal Kulkarni
8127e6ad46Vishal Kulkarni	ulprx_la_buff = (struct struct_ulprx_la *) scratch_buff.data;
8137e6ad46Vishal Kulkarni	t4_ulprx_read_la(padap, (u32 *)ulprx_la_buff->data);
8147e6ad46Vishal Kulkarni	ulprx_la_buff->size = ULPRX_LA_SIZE;
8157e6ad46Vishal Kulkarni
8167e6ad46Vishal Kulkarni	rc = write_compression_hdr(&scratch_buff, dbg_buff);
8177e6ad46Vishal Kulkarni	if (rc)
8187e6ad46Vishal Kulkarni		goto err1;
8197e6ad46Vishal Kulkarni
8207e6ad46Vishal Kulkarni	rc = compress_buff(&scratch_buff, dbg_buff);
8217e6ad46Vishal Kulkarni
8227e6ad46Vishal Kulkarnierr1:
8237e6ad46Vishal Kulkarni	release_scratch_buff(&scratch_buff, dbg_buff);
8247e6ad46Vishal Kulkarnierr:
8257e6ad46Vishal Kulkarni	return rc;
8267e6ad46Vishal Kulkarni}
8277e6ad46Vishal Kulkarni
8287e6ad46Vishal Kulkarnistatic int
8297e6ad46Vishal Kulkarnicollect_cpl_stats(struct cudbg_init *pdbg_init,
8307e6ad46Vishal Kulkarni		  struct cudbg_buffer *dbg_buff,
8317e6ad46Vishal Kulkarni		  struct cudbg_error *cudbg_err)
8327e6ad46Vishal Kulkarni{
8337e6ad46Vishal Kulkarni	struct adapter *padap = pdbg_init->adap;
8347e6ad46Vishal Kulkarni	struct cudbg_buffer scratch_buff;
8357e6ad46Vishal Kulkarni	struct struct_tp_cpl_stats *tp_cpl_stats_buff;
8367e6ad46Vishal Kulkarni	u32 size;
8377e6ad46Vishal Kulkarni	int rc = 0;
8387e6ad46Vishal Kulkarni
8397e6ad46Vishal Kulkarni	size = sizeof(struct struct_tp_cpl_stats);
8407e6ad46Vishal Kulkarni
8417e6ad46Vishal Kulkarni	rc = get_scratch_buff(dbg_buff, size, &scratch_buff);
8427e6ad46Vishal Kulkarni	if (rc)
8437e6ad46Vishal Kulkarni		goto err;
8447e6ad46Vishal Kulkarni
8457e6ad46Vishal Kulkarni	tp_cpl_stats_buff = (struct struct_tp_cpl_stats *) scratch_buff.data;
8467e6ad46Vishal Kulkarni	tp_cpl_stats_buff->nchan = padap->params.arch.nchan;
8477e6ad46Vishal Kulkarni
8487e6ad46Vishal Kulkarni	t4_tp_get_cpl_stats(padap, &tp_cpl_stats_buff->stats, 1);
8497e6ad46Vishal Kulkarni
8507e6ad46Vishal Kulkarni	rc = write_compression_hdr(&scratch_buff, dbg_buff);
8517e6ad46Vishal Kulkarni	if (rc)
8527e6ad46Vishal Kulkarni		goto err1;
8537e6ad46Vishal Kulkarni
8547e6ad46Vishal Kulkarni	rc = compress_buff(&scratch_buff, dbg_buff);
8557e6ad46Vishal Kulkarni
8567e6ad46Vishal Kulkarnierr1:
8577e6ad46Vishal Kulkarni	release_scratch_buff(&scratch_buff, dbg_buff);
8587e6ad46Vishal Kulkarnierr:
8597e6ad46Vishal Kulkarni	return rc;
8607e6ad46Vishal Kulkarni}
8617e6ad46Vishal Kulkarni
8627e6ad46Vishal Kulkarnistatic int
8637e6ad46Vishal Kulkarnicollect_wc_stats(struct cudbg_init *pdbg_init,
8647e6ad46Vishal Kulkarni		 struct cudbg_buffer *dbg_buff,
8657e6ad46Vishal Kulkarni		 struct cudbg_error *cudbg_err)
8667e6ad46Vishal Kulkarni{
8677e6ad46Vishal Kulkarni	struct adapter *padap = pdbg_init->adap;
8687e6ad46Vishal Kulkarni	struct cudbg_buffer scratch_buff;
8697e6ad46Vishal Kulkarni	struct struct_wc_stats *wc_stats_buff;
8707e6ad46Vishal Kulkarni	u32 val1;
8717e6ad46Vishal Kulkarni	u32 val2;
8727e6ad46Vishal Kulkarni	u32 size;
8737e6ad46Vishal Kulkarni
8747e6ad46Vishal Kulkarni	int rc = 0;
8757e6ad46Vishal Kulkarni
8767e6ad46Vishal Kulkarni	size = sizeof(struct struct_wc_stats);
8777e6ad46Vishal Kulkarni
8787e6ad46Vishal Kulkarni	rc = get_scratch_buff(dbg_buff, size, &scratch_buff);
8797e6ad46Vishal Kulkarni	if (rc)
8807e6ad46Vishal Kulkarni		goto err;
8817e6ad46Vishal Kulkarni
8827e6ad46Vishal Kulkarni	wc_stats_buff = (struct struct_wc_stats *) scratch_buff.data;
8837e6ad46Vishal Kulkarni
8847e6ad46Vishal Kulkarni	if (!is_t4(padap->params.chip)) {
8857e6ad46Vishal Kulkarni		val1 = t4_read_reg(padap, A_SGE_STAT_TOTAL);
8867e6ad46Vishal Kulkarni		val2 = t4_read_reg(padap, A_SGE_STAT_MATCH);
8877e6ad46Vishal Kulkarni		wc_stats_buff->wr_cl_success = val1 - val2;
8887e6ad46Vishal Kulkarni		wc_stats_buff->wr_cl_fail = val2;
8897e6ad46Vishal Kulkarni	} else {
8907e6ad46Vishal Kulkarni		wc_stats_buff->wr_cl_success = 0;
8917e6ad46Vishal Kulkarni		wc_stats_buff->wr_cl_fail = 0;
8927e6ad46Vishal Kulkarni	}
8937e6ad46Vishal Kulkarni
8947e6ad46Vishal Kulkarni	rc = write_compression_hdr(&scratch_buff, dbg_buff);
8957e6ad46Vishal Kulkarni	if (rc)
8967e6ad46Vishal Kulkarni		goto err1;
8977e6ad46Vishal Kulkarni
8987e6ad46Vishal Kulkarni	rc = compress_buff(&scratch_buff, dbg_buff);
8997e6ad46Vishal Kulkarnierr1:
9007e6ad46Vishal Kulkarni	release_scratch_buff(&scratch_buff, dbg_buff);
9017e6ad46Vishal Kulkarnierr:
9027e6ad46Vishal Kulkarni	return rc;
9037e6ad46Vishal Kulkarni}
9047e6ad46Vishal Kulkarni