17e6ad469SVishal Kulkarni /*
27e6ad469SVishal Kulkarni  * This file and its contents are supplied under the terms of the
37e6ad469SVishal Kulkarni  * Common Development and Distribution License ("CDDL"), version 1.0.
47e6ad469SVishal Kulkarni  * You may only use this file in accordance with the terms of version
57e6ad469SVishal Kulkarni  * 1.0 of the CDDL.
67e6ad469SVishal Kulkarni  *
77e6ad469SVishal Kulkarni  * A full copy of the text of the CDDL should have accompanied this
87e6ad469SVishal Kulkarni  * source. A copy of the CDDL is also available via the Internet at
97e6ad469SVishal Kulkarni  * http://www.illumos.org/license/CDDL.
107e6ad469SVishal Kulkarni  */
117e6ad469SVishal Kulkarni 
127e6ad469SVishal Kulkarni /*-
137e6ad469SVishal Kulkarni  * Copyright (c) 2019 Chelsio Communications, Inc.
147e6ad469SVishal Kulkarni  * All rights reserved.
157e6ad469SVishal Kulkarni  *
167e6ad469SVishal Kulkarni  * Redistribution and use in source and binary forms, with or without
177e6ad469SVishal Kulkarni  * modification, are permitted provided that the following conditions
187e6ad469SVishal Kulkarni  * are met:
197e6ad469SVishal Kulkarni  * 1. Redistributions of source code must retain the above copyright
207e6ad469SVishal Kulkarni  *    notice, this list of conditions and the following disclaimer.
217e6ad469SVishal Kulkarni  * 2. Redistributions in binary form must reproduce the above copyright
227e6ad469SVishal Kulkarni  *    notice, this list of conditions and the following disclaimer in the
237e6ad469SVishal Kulkarni  *    documentation and/or other materials provided with the distribution.
247e6ad469SVishal Kulkarni  *
257e6ad469SVishal Kulkarni  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
267e6ad469SVishal Kulkarni  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
277e6ad469SVishal Kulkarni  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
287e6ad469SVishal Kulkarni  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
297e6ad469SVishal Kulkarni  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
307e6ad469SVishal Kulkarni  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
317e6ad469SVishal Kulkarni  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
327e6ad469SVishal Kulkarni  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
337e6ad469SVishal Kulkarni  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
347e6ad469SVishal Kulkarni  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
357e6ad469SVishal Kulkarni  * SUCH DAMAGE.
367e6ad469SVishal Kulkarni  */
377e6ad469SVishal Kulkarni 
387e6ad469SVishal Kulkarni #include <sys/types.h>
397e6ad469SVishal Kulkarni #include <sys/param.h>
407e6ad469SVishal Kulkarni 
417e6ad469SVishal Kulkarni #include "common/common.h"
427e6ad469SVishal Kulkarni #include "common/t4_regs.h"
437e6ad469SVishal Kulkarni #include "common/t4_chip_type.h"
447e6ad469SVishal Kulkarni #include "cudbg.h"
457e6ad469SVishal Kulkarni #include "cudbg_lib_common.h"
467e6ad469SVishal Kulkarni #include "cudbg_lib.h"
477e6ad469SVishal Kulkarni #include "cudbg_entity.h"
487e6ad469SVishal Kulkarni 
497e6ad469SVishal Kulkarni #define  BUFFER_WARN_LIMIT 10000000
507e6ad469SVishal Kulkarni 
517e6ad469SVishal Kulkarni struct large_entity large_entity_list[] = {
527e6ad469SVishal Kulkarni 	{CUDBG_EDC0, 0, 0},
537e6ad469SVishal Kulkarni 	{CUDBG_EDC1, 0 , 0},
547e6ad469SVishal Kulkarni 	{CUDBG_MC0, 0, 0},
557e6ad469SVishal Kulkarni 	{CUDBG_MC1, 0, 0}
567e6ad469SVishal Kulkarni };
577e6ad469SVishal Kulkarni 
587e6ad469SVishal Kulkarni static int
is_fw_attached(struct cudbg_init * pdbg_init)597e6ad469SVishal Kulkarni is_fw_attached(struct cudbg_init *pdbg_init)
607e6ad469SVishal Kulkarni {
617e6ad469SVishal Kulkarni 
627e6ad469SVishal Kulkarni 	return (pdbg_init->adap->flags & FW_OK);
637e6ad469SVishal Kulkarni }
647e6ad469SVishal Kulkarni 
657e6ad469SVishal Kulkarni /* This function will add additional padding bytes into debug_buffer to make it
667e6ad469SVishal Kulkarni  * 4 byte aligned.*/
677e6ad469SVishal Kulkarni static void
align_debug_buffer(struct cudbg_buffer * dbg_buff,struct cudbg_entity_hdr * entity_hdr)687e6ad469SVishal Kulkarni align_debug_buffer(struct cudbg_buffer *dbg_buff,
697e6ad469SVishal Kulkarni 		   struct cudbg_entity_hdr *entity_hdr)
707e6ad469SVishal Kulkarni {
717e6ad469SVishal Kulkarni 	u8 zero_buf[4] = {0};
727e6ad469SVishal Kulkarni 	u8 padding, remain;
737e6ad469SVishal Kulkarni 
747e6ad469SVishal Kulkarni 	remain = (dbg_buff->offset - entity_hdr->start_offset) % 4;
757e6ad469SVishal Kulkarni 	padding = 4 - remain;
767e6ad469SVishal Kulkarni 	if (remain) {
777e6ad469SVishal Kulkarni 		memcpy(((u8 *) dbg_buff->data) + dbg_buff->offset, &zero_buf,
787e6ad469SVishal Kulkarni 		       padding);
797e6ad469SVishal Kulkarni 		dbg_buff->offset += padding;
807e6ad469SVishal Kulkarni 		entity_hdr->num_pad = padding;
817e6ad469SVishal Kulkarni 	}
827e6ad469SVishal Kulkarni 
837e6ad469SVishal Kulkarni 	entity_hdr->size = dbg_buff->offset - entity_hdr->start_offset;
847e6ad469SVishal Kulkarni }
857e6ad469SVishal Kulkarni 
867e6ad469SVishal Kulkarni static void
u32_swap(void * a,void * b,int size)877e6ad469SVishal Kulkarni u32_swap(void *a, void *b, int size)
887e6ad469SVishal Kulkarni {
897e6ad469SVishal Kulkarni         u32 t = *(u32 *)a;
907e6ad469SVishal Kulkarni 
917e6ad469SVishal Kulkarni         *(u32 *)a = *(u32 *)b;
927e6ad469SVishal Kulkarni         *(u32 *)b = t;
937e6ad469SVishal Kulkarni }
947e6ad469SVishal Kulkarni 
957e6ad469SVishal Kulkarni static void
generic_swap(void * a1,void * b1,int size)967e6ad469SVishal Kulkarni generic_swap(void *a1, void *b1, int size)
977e6ad469SVishal Kulkarni {
987e6ad469SVishal Kulkarni 	u8 t;
997e6ad469SVishal Kulkarni 	u8 *a = (u8 *)a1;
1007e6ad469SVishal Kulkarni 	u8 *b = (u8 *)b1;
1017e6ad469SVishal Kulkarni 
1027e6ad469SVishal Kulkarni 	do {
1037e6ad469SVishal Kulkarni 		t = *a;
1047e6ad469SVishal Kulkarni 		*(a++) = *b;
1057e6ad469SVishal Kulkarni 		*(b++) = t;
1067e6ad469SVishal Kulkarni 	} while (--size > 0);
1077e6ad469SVishal Kulkarni }
1087e6ad469SVishal Kulkarni 
1097e6ad469SVishal Kulkarni static void
qsort(void * base_val,int num,int size,int (* cmp_func)(const void *,const void *),void (* swap_func)(void *,void *,int size))1107e6ad469SVishal Kulkarni qsort(void *base_val, int num, int size,
1117e6ad469SVishal Kulkarni       int (*cmp_func)(const void *, const void *),
1127e6ad469SVishal Kulkarni       void (*swap_func)(void *, void *, int size))
1137e6ad469SVishal Kulkarni {
1147e6ad469SVishal Kulkarni 	/* pre-scale counters for performance */
1157e6ad469SVishal Kulkarni 	int i = (num / 2 - 1) * size;
1167e6ad469SVishal Kulkarni 	int n = num * size;
1177e6ad469SVishal Kulkarni 	int c, r;
1187e6ad469SVishal Kulkarni 	u8 *base = (u8 *)base_val;
1197e6ad469SVishal Kulkarni 
1207e6ad469SVishal Kulkarni 	if (!swap_func)
1217e6ad469SVishal Kulkarni 		swap_func = (size == 4 ? u32_swap : generic_swap);
1227e6ad469SVishal Kulkarni 
1237e6ad469SVishal Kulkarni 	/* heapify */
1247e6ad469SVishal Kulkarni 	for (; i >= 0; i -= size) {
1257e6ad469SVishal Kulkarni 		for (r = i; r * 2 + size < n; r  = c) {
1267e6ad469SVishal Kulkarni 			c = r * 2 + size;
1277e6ad469SVishal Kulkarni 			if (c < n - size &&
1287e6ad469SVishal Kulkarni 					cmp_func(base + c, base + c + size) < 0)
1297e6ad469SVishal Kulkarni 				c += size;
1307e6ad469SVishal Kulkarni 			if (cmp_func(base + r, base + c) >= 0)
1317e6ad469SVishal Kulkarni 				break;
1327e6ad469SVishal Kulkarni 			swap_func(base + r, base + c, size);
1337e6ad469SVishal Kulkarni 		}
1347e6ad469SVishal Kulkarni 	}
1357e6ad469SVishal Kulkarni 
1367e6ad469SVishal Kulkarni 	/* sort */
1377e6ad469SVishal Kulkarni 	for (i = n - size; i > 0; i -= size) {
1387e6ad469SVishal Kulkarni 		swap_func(base, base + i, size);
1397e6ad469SVishal Kulkarni 		for (r = 0; r * 2 + size < i; r = c) {
1407e6ad469SVishal Kulkarni 			c = r * 2 + size;
1417e6ad469SVishal Kulkarni 			if (c < i - size &&
1427e6ad469SVishal Kulkarni 					cmp_func(base + c, base + c + size) < 0)
1437e6ad469SVishal Kulkarni 				c += size;
1447e6ad469SVishal Kulkarni 			if (cmp_func(base + r, base + c) >= 0)
1457e6ad469SVishal Kulkarni 				break;
1467e6ad469SVishal Kulkarni 			swap_func(base + r, base + c, size);
1477e6ad469SVishal Kulkarni 		}
1487e6ad469SVishal Kulkarni 	}
1497e6ad469SVishal Kulkarni }
1507e6ad469SVishal Kulkarni 
1517e6ad469SVishal Kulkarni static void
read_sge_ctxt(struct cudbg_init * pdbg_init,u32 cid,enum ctxt_type ctype,u32 * data)1527e6ad469SVishal Kulkarni read_sge_ctxt(struct cudbg_init *pdbg_init, u32 cid,
1537e6ad469SVishal Kulkarni 	      enum ctxt_type ctype, u32 *data)
1547e6ad469SVishal Kulkarni {
1557e6ad469SVishal Kulkarni 	struct adapter *padap = pdbg_init->adap;
1567e6ad469SVishal Kulkarni 	int rc = -1;
1577e6ad469SVishal Kulkarni 
1587e6ad469SVishal Kulkarni 	if (is_fw_attached(pdbg_init)) {
1597e6ad469SVishal Kulkarni 		rc =begin_synchronized_op(padap->port[0], 1, 1);
1607e6ad469SVishal Kulkarni 		if (rc != 0)
1617e6ad469SVishal Kulkarni 			goto out;
1627e6ad469SVishal Kulkarni 		rc = t4_sge_ctxt_rd(padap, padap->mbox, cid, ctype,
1637e6ad469SVishal Kulkarni 				    data);
1647e6ad469SVishal Kulkarni 		end_synchronized_op(padap->port[0], 1);
1657e6ad469SVishal Kulkarni 	}
1667e6ad469SVishal Kulkarni 
1677e6ad469SVishal Kulkarni out:
1687e6ad469SVishal Kulkarni 	if (rc)
1697e6ad469SVishal Kulkarni 		t4_sge_ctxt_rd_bd(padap, cid, ctype, data);
1707e6ad469SVishal Kulkarni }
1717e6ad469SVishal Kulkarni 
1727e6ad469SVishal Kulkarni static int
get_next_ext_entity_hdr(void * outbuf,u32 * ext_size,struct cudbg_buffer * dbg_buff,struct cudbg_entity_hdr ** entity_hdr)1737e6ad469SVishal Kulkarni get_next_ext_entity_hdr(void *outbuf, u32 *ext_size,
1747e6ad469SVishal Kulkarni 			struct cudbg_buffer *dbg_buff,
1757e6ad469SVishal Kulkarni 			struct cudbg_entity_hdr **entity_hdr)
1767e6ad469SVishal Kulkarni {
1777e6ad469SVishal Kulkarni 	struct cudbg_hdr *cudbg_hdr = (struct cudbg_hdr *)outbuf;
1787e6ad469SVishal Kulkarni 	int rc = 0;
1797e6ad469SVishal Kulkarni 	u32 ext_offset = cudbg_hdr->data_len;
1807e6ad469SVishal Kulkarni 	*ext_size = 0;
1817e6ad469SVishal Kulkarni 
1827e6ad469SVishal Kulkarni 	if (dbg_buff->size - dbg_buff->offset <=
1837e6ad469SVishal Kulkarni 		 sizeof(struct cudbg_entity_hdr)) {
1847e6ad469SVishal Kulkarni 		rc = CUDBG_STATUS_BUFFER_SHORT;
1857e6ad469SVishal Kulkarni 		goto err;
1867e6ad469SVishal Kulkarni 	}
1877e6ad469SVishal Kulkarni 
1887e6ad469SVishal Kulkarni 	*entity_hdr = (struct cudbg_entity_hdr *)
1897e6ad469SVishal Kulkarni 		       ((char *)outbuf + cudbg_hdr->data_len);
1907e6ad469SVishal Kulkarni 
1917e6ad469SVishal Kulkarni 	/* Find the last extended entity header */
1927e6ad469SVishal Kulkarni 	while ((*entity_hdr)->size) {
1937e6ad469SVishal Kulkarni 
1947e6ad469SVishal Kulkarni 		ext_offset += sizeof(struct cudbg_entity_hdr) +
1957e6ad469SVishal Kulkarni 				     (*entity_hdr)->size;
1967e6ad469SVishal Kulkarni 
1977e6ad469SVishal Kulkarni 		*ext_size += (*entity_hdr)->size +
1987e6ad469SVishal Kulkarni 			      sizeof(struct cudbg_entity_hdr);
1997e6ad469SVishal Kulkarni 
2007e6ad469SVishal Kulkarni 		if (dbg_buff->size - dbg_buff->offset + *ext_size  <=
2017e6ad469SVishal Kulkarni 			sizeof(struct cudbg_entity_hdr)) {
2027e6ad469SVishal Kulkarni 			rc = CUDBG_STATUS_BUFFER_SHORT;
2037e6ad469SVishal Kulkarni 			goto err;
2047e6ad469SVishal Kulkarni 		}
2057e6ad469SVishal Kulkarni 
2067e6ad469SVishal Kulkarni 		if (ext_offset != (*entity_hdr)->next_ext_offset) {
2077e6ad469SVishal Kulkarni 			ext_offset -= sizeof(struct cudbg_entity_hdr) +
2087e6ad469SVishal Kulkarni 				     (*entity_hdr)->size;
2097e6ad469SVishal Kulkarni 			break;
2107e6ad469SVishal Kulkarni 		}
2117e6ad469SVishal Kulkarni 
2127e6ad469SVishal Kulkarni 		(*entity_hdr)->next_ext_offset = *ext_size;
2137e6ad469SVishal Kulkarni 
2147e6ad469SVishal Kulkarni 		*entity_hdr = (struct cudbg_entity_hdr *)
2157e6ad469SVishal Kulkarni 					   ((char *)outbuf +
2167e6ad469SVishal Kulkarni 					   ext_offset);
2177e6ad469SVishal Kulkarni 	}
2187e6ad469SVishal Kulkarni 
2197e6ad469SVishal Kulkarni 	/* update the data offset */
2207e6ad469SVishal Kulkarni 	dbg_buff->offset = ext_offset;
2217e6ad469SVishal Kulkarni err:
2227e6ad469SVishal Kulkarni 	return rc;
2237e6ad469SVishal Kulkarni }
2247e6ad469SVishal Kulkarni 
2257e6ad469SVishal Kulkarni static int
wr_entity_to_flash(void * handle,struct cudbg_buffer * dbg_buff,u32 cur_entity_data_offset,u32 cur_entity_size,int entity_nu,u32 ext_size)2267e6ad469SVishal Kulkarni wr_entity_to_flash(void *handle, struct cudbg_buffer *dbg_buff,
2277e6ad469SVishal Kulkarni 		   u32 cur_entity_data_offset,
2287e6ad469SVishal Kulkarni 		   u32 cur_entity_size,
2297e6ad469SVishal Kulkarni 		   int entity_nu, u32 ext_size)
2307e6ad469SVishal Kulkarni {
2317e6ad469SVishal Kulkarni 	struct cudbg_private *priv = handle;
2327e6ad469SVishal Kulkarni 	struct cudbg_init *cudbg_init = &priv->dbg_init;
2337e6ad469SVishal Kulkarni 	struct cudbg_flash_sec_info *sec_info = &priv->sec_info;
2347e6ad469SVishal Kulkarni 	struct adapter *adap = cudbg_init->adap;
2357e6ad469SVishal Kulkarni 	u64 timestamp;
2367e6ad469SVishal Kulkarni 	u32 cur_entity_hdr_offset = sizeof(struct cudbg_hdr);
2377e6ad469SVishal Kulkarni 	u32 remain_flash_size;
2387e6ad469SVishal Kulkarni 	u32 flash_data_offset;
2397e6ad469SVishal Kulkarni 	u32 data_hdr_size;
2407e6ad469SVishal Kulkarni 	int rc = -1;
2417e6ad469SVishal Kulkarni 
2427e6ad469SVishal Kulkarni 	data_hdr_size = CUDBG_MAX_ENTITY * sizeof(struct cudbg_entity_hdr) +
2437e6ad469SVishal Kulkarni 			sizeof(struct cudbg_hdr);
2447e6ad469SVishal Kulkarni 
2457e6ad469SVishal Kulkarni 	flash_data_offset = (FLASH_CUDBG_NSECS *
2467e6ad469SVishal Kulkarni 			     (sizeof(struct cudbg_flash_hdr) +
2477e6ad469SVishal Kulkarni 			      data_hdr_size)) +
2487e6ad469SVishal Kulkarni 			    (cur_entity_data_offset - data_hdr_size);
2497e6ad469SVishal Kulkarni 
2507e6ad469SVishal Kulkarni 	if (flash_data_offset > CUDBG_FLASH_SIZE) {
2517e6ad469SVishal Kulkarni 		update_skip_size(sec_info, cur_entity_size);
2527e6ad469SVishal Kulkarni 		if (cudbg_init->verbose)
2537e6ad469SVishal Kulkarni 			cudbg_init->print(adap->dip, CE_NOTE,
2547e6ad469SVishal Kulkarni 					  "Large entity skipping...\n");
2557e6ad469SVishal Kulkarni 		return rc;
2567e6ad469SVishal Kulkarni 	}
2577e6ad469SVishal Kulkarni 
2587e6ad469SVishal Kulkarni 	remain_flash_size = CUDBG_FLASH_SIZE - flash_data_offset;
2597e6ad469SVishal Kulkarni 
2607e6ad469SVishal Kulkarni 	if (cur_entity_size > remain_flash_size) {
2617e6ad469SVishal Kulkarni 		update_skip_size(sec_info, cur_entity_size);
2627e6ad469SVishal Kulkarni 		if (cudbg_init->verbose)
2637e6ad469SVishal Kulkarni 			cudbg_init->print(adap->dip, CE_NOTE,
2647e6ad469SVishal Kulkarni 					  "Large entity skipping...\n");
2657e6ad469SVishal Kulkarni 	} else {
2667e6ad469SVishal Kulkarni 		timestamp = 0;
2677e6ad469SVishal Kulkarni 
2687e6ad469SVishal Kulkarni 		cur_entity_hdr_offset +=
2697e6ad469SVishal Kulkarni 			(sizeof(struct cudbg_entity_hdr) *
2707e6ad469SVishal Kulkarni 			(entity_nu - 1));
2717e6ad469SVishal Kulkarni 
2727e6ad469SVishal Kulkarni 		rc = cudbg_write_flash(handle, timestamp, dbg_buff,
2737e6ad469SVishal Kulkarni 				       cur_entity_data_offset,
2747e6ad469SVishal Kulkarni 				       cur_entity_hdr_offset,
2757e6ad469SVishal Kulkarni 				       cur_entity_size,
2767e6ad469SVishal Kulkarni 				       ext_size);
2777e6ad469SVishal Kulkarni 		if (rc == CUDBG_STATUS_FLASH_FULL && cudbg_init->verbose)
2787e6ad469SVishal Kulkarni 			cudbg_init->print(adap->dip, CE_NOTE,
2797e6ad469SVishal Kulkarni 					  "\n\tFLASH is full... "
2807e6ad469SVishal Kulkarni 					  "can not write in flash more\n\n");
2817e6ad469SVishal Kulkarni 	}
2827e6ad469SVishal Kulkarni 
2837e6ad469SVishal Kulkarni 	return rc;
2847e6ad469SVishal Kulkarni }
2857e6ad469SVishal Kulkarni 
2867e6ad469SVishal Kulkarni int
cudbg_collect(void * handle,void * outbuf,u32 * outbuf_size)2877e6ad469SVishal Kulkarni cudbg_collect(void *handle, void *outbuf, u32 *outbuf_size)
2887e6ad469SVishal Kulkarni {
2897e6ad469SVishal Kulkarni 	struct cudbg_entity_hdr *entity_hdr = NULL;
2907e6ad469SVishal Kulkarni 	struct cudbg_entity_hdr *ext_entity_hdr = NULL;
2917e6ad469SVishal Kulkarni 	struct cudbg_hdr *cudbg_hdr;
2927e6ad469SVishal Kulkarni 	struct cudbg_buffer dbg_buff;
2937e6ad469SVishal Kulkarni 	struct cudbg_error cudbg_err = {0};
2947e6ad469SVishal Kulkarni 	int large_entity_code;
2957e6ad469SVishal Kulkarni 
2967e6ad469SVishal Kulkarni 	u8 *dbg_bitmap = ((struct cudbg_private *)handle)->dbg_init.dbg_bitmap;
2977e6ad469SVishal Kulkarni 	struct cudbg_init *cudbg_init =
2987e6ad469SVishal Kulkarni 		&(((struct cudbg_private *)handle)->dbg_init);
2997e6ad469SVishal Kulkarni 	struct adapter *padap = cudbg_init->adap;
3007e6ad469SVishal Kulkarni 	u32 total_size, remaining_buf_size;
3017e6ad469SVishal Kulkarni 	u32 ext_size = 0;
3027e6ad469SVishal Kulkarni 	int index, bit, i, rc = -1;
3037e6ad469SVishal Kulkarni 	int all;
3047e6ad469SVishal Kulkarni 	bool flag_ext = 0;
3057e6ad469SVishal Kulkarni 
3067e6ad469SVishal Kulkarni 	reset_skip_entity();
3077e6ad469SVishal Kulkarni 
3087e6ad469SVishal Kulkarni 	dbg_buff.data = outbuf;
3097e6ad469SVishal Kulkarni 	dbg_buff.size = *outbuf_size;
3107e6ad469SVishal Kulkarni 	dbg_buff.offset = 0;
3117e6ad469SVishal Kulkarni 
3127e6ad469SVishal Kulkarni 	cudbg_hdr = (struct cudbg_hdr *)dbg_buff.data;
3137e6ad469SVishal Kulkarni 	cudbg_hdr->signature = CUDBG_SIGNATURE;
3147e6ad469SVishal Kulkarni 	cudbg_hdr->hdr_len = sizeof(struct cudbg_hdr);
3157e6ad469SVishal Kulkarni 	cudbg_hdr->major_ver = CUDBG_MAJOR_VERSION;
3167e6ad469SVishal Kulkarni 	cudbg_hdr->minor_ver = CUDBG_MINOR_VERSION;
3177e6ad469SVishal Kulkarni 	cudbg_hdr->max_entities = CUDBG_MAX_ENTITY;
3187e6ad469SVishal Kulkarni 	cudbg_hdr->chip_ver = padap->params.chip;
3197e6ad469SVishal Kulkarni 
3207e6ad469SVishal Kulkarni 	if (cudbg_hdr->data_len)
3217e6ad469SVishal Kulkarni 		flag_ext = 1;
3227e6ad469SVishal Kulkarni 
3237e6ad469SVishal Kulkarni 	if (sizeof(struct cudbg_entity_hdr) * CUDBG_MAX_ENTITY >
3247e6ad469SVishal Kulkarni 	    dbg_buff.size) {
3257e6ad469SVishal Kulkarni 		rc = CUDBG_STATUS_SMALL_BUFF;
3267e6ad469SVishal Kulkarni 		total_size = cudbg_hdr->hdr_len;
3277e6ad469SVishal Kulkarni 		goto err;
3287e6ad469SVishal Kulkarni 	}
3297e6ad469SVishal Kulkarni 
3307e6ad469SVishal Kulkarni 	/* If ext flag is set then move the offset to the end of the buf
3317e6ad469SVishal Kulkarni 	 * so that we can add ext entities
3327e6ad469SVishal Kulkarni 	 */
3337e6ad469SVishal Kulkarni 	if (flag_ext) {
3347e6ad469SVishal Kulkarni 		ext_entity_hdr = (struct cudbg_entity_hdr *)
3357e6ad469SVishal Kulkarni 			      ((char *)outbuf + cudbg_hdr->hdr_len +
3367e6ad469SVishal Kulkarni 			      (sizeof(struct cudbg_entity_hdr) *
3377e6ad469SVishal Kulkarni 			      (CUDBG_EXT_ENTITY - 1)));
3387e6ad469SVishal Kulkarni 		ext_entity_hdr->start_offset = cudbg_hdr->data_len;
3397e6ad469SVishal Kulkarni 		ext_entity_hdr->entity_type = CUDBG_EXT_ENTITY;
3407e6ad469SVishal Kulkarni 		ext_entity_hdr->size = 0;
3417e6ad469SVishal Kulkarni 		dbg_buff.offset = cudbg_hdr->data_len;
3427e6ad469SVishal Kulkarni 	} else {
3437e6ad469SVishal Kulkarni 		dbg_buff.offset += cudbg_hdr->hdr_len; /* move 24 bytes*/
3447e6ad469SVishal Kulkarni 		dbg_buff.offset += CUDBG_MAX_ENTITY *
3457e6ad469SVishal Kulkarni 					sizeof(struct cudbg_entity_hdr);
3467e6ad469SVishal Kulkarni 	}
3477e6ad469SVishal Kulkarni 
3487e6ad469SVishal Kulkarni 	total_size = dbg_buff.offset;
3497e6ad469SVishal Kulkarni 	all = dbg_bitmap[0] & (1 << CUDBG_ALL);
3507e6ad469SVishal Kulkarni 
3517e6ad469SVishal Kulkarni 	for (i = 1; i < CUDBG_MAX_ENTITY; i++) {
3527e6ad469SVishal Kulkarni 		index = i / 8;
3537e6ad469SVishal Kulkarni 		bit = i % 8;
3547e6ad469SVishal Kulkarni 
3557e6ad469SVishal Kulkarni 		if (entity_list[i].bit == CUDBG_EXT_ENTITY)
3567e6ad469SVishal Kulkarni 			continue;
3577e6ad469SVishal Kulkarni 
3587e6ad469SVishal Kulkarni 		if (all || (dbg_bitmap[index] & (1 << bit))) {
3597e6ad469SVishal Kulkarni 
3607e6ad469SVishal Kulkarni 			if (!flag_ext) {
3617e6ad469SVishal Kulkarni 				rc = get_entity_hdr(outbuf, i, dbg_buff.size,
3627e6ad469SVishal Kulkarni 						    &entity_hdr);
3637e6ad469SVishal Kulkarni 				if (rc)
3647e6ad469SVishal Kulkarni 					cudbg_hdr->hdr_flags = rc;
3657e6ad469SVishal Kulkarni 			} else {
3667e6ad469SVishal Kulkarni 				rc = get_next_ext_entity_hdr(outbuf, &ext_size,
3677e6ad469SVishal Kulkarni 							     &dbg_buff,
3687e6ad469SVishal Kulkarni 							     &entity_hdr);
3697e6ad469SVishal Kulkarni 				if (rc)
3707e6ad469SVishal Kulkarni 					goto err;
3717e6ad469SVishal Kulkarni 
3727e6ad469SVishal Kulkarni 				/* move the offset after the ext header */
3737e6ad469SVishal Kulkarni 				dbg_buff.offset +=
3747e6ad469SVishal Kulkarni 					sizeof(struct cudbg_entity_hdr);
3757e6ad469SVishal Kulkarni 			}
3767e6ad469SVishal Kulkarni 
3777e6ad469SVishal Kulkarni 			entity_hdr->entity_type = i;
3787e6ad469SVishal Kulkarni 			entity_hdr->start_offset = dbg_buff.offset;
3797e6ad469SVishal Kulkarni 			/* process each entity by calling process_entity fp */
3807e6ad469SVishal Kulkarni 			remaining_buf_size = dbg_buff.size - dbg_buff.offset;
3817e6ad469SVishal Kulkarni 
3827e6ad469SVishal Kulkarni 			if ((remaining_buf_size <= BUFFER_WARN_LIMIT) &&
3837e6ad469SVishal Kulkarni 			    is_large_entity(i)) {
3847e6ad469SVishal Kulkarni 				if (cudbg_init->verbose)
3857e6ad469SVishal Kulkarni 					cudbg_init->print(padap->dip, CE_NOTE,
3867e6ad469SVishal Kulkarni 							  "Skipping %s\n",
3877e6ad469SVishal Kulkarni 					    entity_list[i].name);
3887e6ad469SVishal Kulkarni 				skip_entity(i);
3897e6ad469SVishal Kulkarni 				continue;
3907e6ad469SVishal Kulkarni 			} else {
3917e6ad469SVishal Kulkarni 
3927e6ad469SVishal Kulkarni 				/* If fw_attach is 0, then skip entities which
3937e6ad469SVishal Kulkarni 				 * communicates with firmware
3947e6ad469SVishal Kulkarni 				 */
3957e6ad469SVishal Kulkarni 
3967e6ad469SVishal Kulkarni 				if (!is_fw_attached(cudbg_init) &&
3977e6ad469SVishal Kulkarni 				    (entity_list[i].flag &
3987e6ad469SVishal Kulkarni 				    (1 << ENTITY_FLAG_FW_NO_ATTACH))) {
3997e6ad469SVishal Kulkarni 					if (cudbg_init->verbose)
4007e6ad469SVishal Kulkarni 						cudbg_init->print(padap->dip, CE_NOTE,
4017e6ad469SVishal Kulkarni 							  "Skipping %s entity,"\
4027e6ad469SVishal Kulkarni 							  "because fw_attach "\
4037e6ad469SVishal Kulkarni 							  "is 0\n",
4047e6ad469SVishal Kulkarni 							  entity_list[i].name);
4057e6ad469SVishal Kulkarni 					continue;
4067e6ad469SVishal Kulkarni 				}
4077e6ad469SVishal Kulkarni 
4087e6ad469SVishal Kulkarni 				if (cudbg_init->verbose)
4097e6ad469SVishal Kulkarni 					cudbg_init->print(padap->dip, CE_NOTE,
4107e6ad469SVishal Kulkarni 							  "collecting debug entity: "\
4117e6ad469SVishal Kulkarni 						  "%s\n", entity_list[i].name);
4127e6ad469SVishal Kulkarni 				memset(&cudbg_err, 0,
4137e6ad469SVishal Kulkarni 				       sizeof(struct cudbg_error));
4147e6ad469SVishal Kulkarni 				rc = process_entity[i-1](cudbg_init, &dbg_buff,
4157e6ad469SVishal Kulkarni 							 &cudbg_err);
4167e6ad469SVishal Kulkarni 			}
4177e6ad469SVishal Kulkarni 
4187e6ad469SVishal Kulkarni 			if (rc) {
4197e6ad469SVishal Kulkarni 				entity_hdr->size = 0;
4207e6ad469SVishal Kulkarni 				dbg_buff.offset = entity_hdr->start_offset;
4217e6ad469SVishal Kulkarni 			} else
4227e6ad469SVishal Kulkarni 				align_debug_buffer(&dbg_buff, entity_hdr);
4237e6ad469SVishal Kulkarni 
4247e6ad469SVishal Kulkarni 			if (cudbg_err.sys_err)
4257e6ad469SVishal Kulkarni 				rc = CUDBG_SYSTEM_ERROR;
4267e6ad469SVishal Kulkarni 
4277e6ad469SVishal Kulkarni 			entity_hdr->hdr_flags =  rc;
4287e6ad469SVishal Kulkarni 			entity_hdr->sys_err = cudbg_err.sys_err;
4297e6ad469SVishal Kulkarni 			entity_hdr->sys_warn =	cudbg_err.sys_warn;
4307e6ad469SVishal Kulkarni 
4317e6ad469SVishal Kulkarni 			/* We don't want to include ext entity size in global
4327e6ad469SVishal Kulkarni 			 * header
4337e6ad469SVishal Kulkarni 			 */
4347e6ad469SVishal Kulkarni 			if (!flag_ext)
4357e6ad469SVishal Kulkarni 				total_size += entity_hdr->size;
4367e6ad469SVishal Kulkarni 
4377e6ad469SVishal Kulkarni 			cudbg_hdr->data_len = total_size;
4387e6ad469SVishal Kulkarni 			*outbuf_size = total_size;
4397e6ad469SVishal Kulkarni 
4407e6ad469SVishal Kulkarni 			/* consider the size of the ext entity header and data
4417e6ad469SVishal Kulkarni 			 * also
4427e6ad469SVishal Kulkarni 			 */
4437e6ad469SVishal Kulkarni 			if (flag_ext) {
4447e6ad469SVishal Kulkarni 				ext_size += (sizeof(struct cudbg_entity_hdr) +
4457e6ad469SVishal Kulkarni 					     entity_hdr->size);
4467e6ad469SVishal Kulkarni 				entity_hdr->start_offset -= cudbg_hdr->data_len;
4477e6ad469SVishal Kulkarni 				ext_entity_hdr->size = ext_size;
4487e6ad469SVishal Kulkarni 				entity_hdr->next_ext_offset = ext_size;
4497e6ad469SVishal Kulkarni 				entity_hdr->flag |= CUDBG_EXT_DATA_VALID;
4507e6ad469SVishal Kulkarni 			}
4517e6ad469SVishal Kulkarni 
4527e6ad469SVishal Kulkarni 			if (cudbg_init->use_flash) {
4537e6ad469SVishal Kulkarni 				if (flag_ext) {
4547e6ad469SVishal Kulkarni 					wr_entity_to_flash(handle,
4557e6ad469SVishal Kulkarni 							   &dbg_buff,
4567e6ad469SVishal Kulkarni 							   ext_entity_hdr->
4577e6ad469SVishal Kulkarni 							   start_offset,
4587e6ad469SVishal Kulkarni 							   entity_hdr->
4597e6ad469SVishal Kulkarni 							   size,
4607e6ad469SVishal Kulkarni 							   CUDBG_EXT_ENTITY,
4617e6ad469SVishal Kulkarni 							   ext_size);
4627e6ad469SVishal Kulkarni 				}
4637e6ad469SVishal Kulkarni 				else
4647e6ad469SVishal Kulkarni 					wr_entity_to_flash(handle,
4657e6ad469SVishal Kulkarni 							   &dbg_buff,
4667e6ad469SVishal Kulkarni 							   entity_hdr->\
4677e6ad469SVishal Kulkarni 							   start_offset,
4687e6ad469SVishal Kulkarni 							   entity_hdr->size,
4697e6ad469SVishal Kulkarni 							   i, ext_size);
4707e6ad469SVishal Kulkarni 			}
4717e6ad469SVishal Kulkarni 		}
4727e6ad469SVishal Kulkarni 	}
4737e6ad469SVishal Kulkarni 
4747e6ad469SVishal Kulkarni 	for (i = 0; i < sizeof(large_entity_list) / sizeof(struct large_entity);
4757e6ad469SVishal Kulkarni 	     i++) {
4767e6ad469SVishal Kulkarni 		large_entity_code = large_entity_list[i].entity_code;
4777e6ad469SVishal Kulkarni 		if (large_entity_list[i].skip_flag) {
4787e6ad469SVishal Kulkarni 			if (!flag_ext) {
4797e6ad469SVishal Kulkarni 				rc = get_entity_hdr(outbuf, large_entity_code,
4807e6ad469SVishal Kulkarni 						    dbg_buff.size, &entity_hdr);
4817e6ad469SVishal Kulkarni 				if (rc)
4827e6ad469SVishal Kulkarni 					cudbg_hdr->hdr_flags = rc;
4837e6ad469SVishal Kulkarni 			} else {
4847e6ad469SVishal Kulkarni 				rc = get_next_ext_entity_hdr(outbuf, &ext_size,
4857e6ad469SVishal Kulkarni 							     &dbg_buff,
4867e6ad469SVishal Kulkarni 							     &entity_hdr);
4877e6ad469SVishal Kulkarni 				if (rc)
4887e6ad469SVishal Kulkarni 					goto err;
4897e6ad469SVishal Kulkarni 
4907e6ad469SVishal Kulkarni 				dbg_buff.offset +=
4917e6ad469SVishal Kulkarni 					sizeof(struct cudbg_entity_hdr);
4927e6ad469SVishal Kulkarni 			}
4937e6ad469SVishal Kulkarni 
4947e6ad469SVishal Kulkarni 			/* If fw_attach is 0, then skip entities which
4957e6ad469SVishal Kulkarni 			 * communicates with firmware
4967e6ad469SVishal Kulkarni 			 */
4977e6ad469SVishal Kulkarni 			if (!is_fw_attached(cudbg_init) &&
4987e6ad469SVishal Kulkarni 			    (entity_list[large_entity_code].flag &
4997e6ad469SVishal Kulkarni 			    (1 << ENTITY_FLAG_FW_NO_ATTACH))) {
5007e6ad469SVishal Kulkarni 				if (cudbg_init->verbose)
5017e6ad469SVishal Kulkarni 					cudbg_init->print(padap->dip, CE_NOTE,
5027e6ad469SVishal Kulkarni 						  "Skipping %s entity,"\
5037e6ad469SVishal Kulkarni 						  "because fw_attach "\
5047e6ad469SVishal Kulkarni 						  "is 0\n",
5057e6ad469SVishal Kulkarni 						  entity_list[large_entity_code]
5067e6ad469SVishal Kulkarni 						  .name);
5077e6ad469SVishal Kulkarni 				continue;
5087e6ad469SVishal Kulkarni 			}
5097e6ad469SVishal Kulkarni 
5107e6ad469SVishal Kulkarni 			entity_hdr->entity_type = large_entity_code;
5117e6ad469SVishal Kulkarni 			entity_hdr->start_offset = dbg_buff.offset;
5127e6ad469SVishal Kulkarni 			if (cudbg_init->verbose)
5137e6ad469SVishal Kulkarni 				cudbg_init->print(padap->dip, CE_NOTE,
5147e6ad469SVishal Kulkarni 					  "Re-trying debug entity: %s\n",
5157e6ad469SVishal Kulkarni 					  entity_list[large_entity_code].name);
5167e6ad469SVishal Kulkarni 
5177e6ad469SVishal Kulkarni 			memset(&cudbg_err, 0, sizeof(struct cudbg_error));
5187e6ad469SVishal Kulkarni 			rc = process_entity[large_entity_code - 1](cudbg_init,
5197e6ad469SVishal Kulkarni 								   &dbg_buff,
5207e6ad469SVishal Kulkarni 								   &cudbg_err);
5217e6ad469SVishal Kulkarni 			if (rc) {
5227e6ad469SVishal Kulkarni 				entity_hdr->size = 0;
5237e6ad469SVishal Kulkarni 				dbg_buff.offset = entity_hdr->start_offset;
5247e6ad469SVishal Kulkarni 			} else
5257e6ad469SVishal Kulkarni 				align_debug_buffer(&dbg_buff, entity_hdr);
5267e6ad469SVishal Kulkarni 
5277e6ad469SVishal Kulkarni 			if (cudbg_err.sys_err)
5287e6ad469SVishal Kulkarni 				rc = CUDBG_SYSTEM_ERROR;
5297e6ad469SVishal Kulkarni 
5307e6ad469SVishal Kulkarni 			entity_hdr->hdr_flags = rc;
5317e6ad469SVishal Kulkarni 			entity_hdr->sys_err = cudbg_err.sys_err;
5327e6ad469SVishal Kulkarni 			entity_hdr->sys_warn =	cudbg_err.sys_warn;
5337e6ad469SVishal Kulkarni 
5347e6ad469SVishal Kulkarni 			/* We don't want to include ext entity size in global
5357e6ad469SVishal Kulkarni 			 * header
5367e6ad469SVishal Kulkarni 			 */
5377e6ad469SVishal Kulkarni 			if (!flag_ext)
5387e6ad469SVishal Kulkarni 				total_size += entity_hdr->size;
5397e6ad469SVishal Kulkarni 
5407e6ad469SVishal Kulkarni 			cudbg_hdr->data_len = total_size;
5417e6ad469SVishal Kulkarni 			*outbuf_size = total_size;
5427e6ad469SVishal Kulkarni 
5437e6ad469SVishal Kulkarni 			/* consider the size of the ext entity header and
5447e6ad469SVishal Kulkarni 			 * data also
5457e6ad469SVishal Kulkarni 			 */
5467e6ad469SVishal Kulkarni 			if (flag_ext) {
5477e6ad469SVishal Kulkarni 				ext_size += (sizeof(struct cudbg_entity_hdr) +
5487e6ad469SVishal Kulkarni 						   entity_hdr->size);
5497e6ad469SVishal Kulkarni 				entity_hdr->start_offset -=
5507e6ad469SVishal Kulkarni 							cudbg_hdr->data_len;
5517e6ad469SVishal Kulkarni 				ext_entity_hdr->size = ext_size;
5527e6ad469SVishal Kulkarni 				entity_hdr->flag |= CUDBG_EXT_DATA_VALID;
5537e6ad469SVishal Kulkarni 			}
5547e6ad469SVishal Kulkarni 
5557e6ad469SVishal Kulkarni 			if (cudbg_init->use_flash) {
5567e6ad469SVishal Kulkarni 				if (flag_ext)
5577e6ad469SVishal Kulkarni 					wr_entity_to_flash(handle,
5587e6ad469SVishal Kulkarni 							   &dbg_buff,
5597e6ad469SVishal Kulkarni 							   ext_entity_hdr->
5607e6ad469SVishal Kulkarni 							   start_offset,
5617e6ad469SVishal Kulkarni 							   entity_hdr->size,
5627e6ad469SVishal Kulkarni 							   CUDBG_EXT_ENTITY,
5637e6ad469SVishal Kulkarni 							   ext_size);
5647e6ad469SVishal Kulkarni 				else
5657e6ad469SVishal Kulkarni 					wr_entity_to_flash(handle,
5667e6ad469SVishal Kulkarni 							   &dbg_buff,
5677e6ad469SVishal Kulkarni 							   entity_hdr->
5687e6ad469SVishal Kulkarni 							   start_offset,
5697e6ad469SVishal Kulkarni 							   entity_hdr->
5707e6ad469SVishal Kulkarni 							   size,
5717e6ad469SVishal Kulkarni 							   large_entity_list[i].
5727e6ad469SVishal Kulkarni 							   entity_code,
5737e6ad469SVishal Kulkarni 							   ext_size);
5747e6ad469SVishal Kulkarni 			}
5757e6ad469SVishal Kulkarni 		}
5767e6ad469SVishal Kulkarni 	}
5777e6ad469SVishal Kulkarni 
5787e6ad469SVishal Kulkarni 	cudbg_hdr->data_len = total_size;
5797e6ad469SVishal Kulkarni 	*outbuf_size = total_size;
5807e6ad469SVishal Kulkarni 
5817e6ad469SVishal Kulkarni 	if (flag_ext)
5827e6ad469SVishal Kulkarni 		*outbuf_size += ext_size;
5837e6ad469SVishal Kulkarni 
5847e6ad469SVishal Kulkarni 	return 0;
5857e6ad469SVishal Kulkarni err:
5867e6ad469SVishal Kulkarni 	return rc;
5877e6ad469SVishal Kulkarni }
5887e6ad469SVishal Kulkarni 
5897e6ad469SVishal Kulkarni void
reset_skip_entity(void)5907e6ad469SVishal Kulkarni reset_skip_entity(void)
5917e6ad469SVishal Kulkarni {
5927e6ad469SVishal Kulkarni 	int i;
5937e6ad469SVishal Kulkarni 
5947e6ad469SVishal Kulkarni 	for (i = 0; i < ARRAY_SIZE(large_entity_list); i++)
5957e6ad469SVishal Kulkarni 		large_entity_list[i].skip_flag = 0;
5967e6ad469SVishal Kulkarni }
5977e6ad469SVishal Kulkarni 
5987e6ad469SVishal Kulkarni void
skip_entity(int entity_code)5997e6ad469SVishal Kulkarni skip_entity(int entity_code)
6007e6ad469SVishal Kulkarni {
6017e6ad469SVishal Kulkarni 	int i;
6027e6ad469SVishal Kulkarni 	for (i = 0; i < sizeof(large_entity_list) / sizeof(struct large_entity);
6037e6ad469SVishal Kulkarni 	     i++) {
6047e6ad469SVishal Kulkarni 		if (large_entity_list[i].entity_code == entity_code)
6057e6ad469SVishal Kulkarni 			large_entity_list[i].skip_flag = 1;
6067e6ad469SVishal Kulkarni 	}
6077e6ad469SVishal Kulkarni }
6087e6ad469SVishal Kulkarni 
6097e6ad469SVishal Kulkarni int
is_large_entity(int entity_code)6107e6ad469SVishal Kulkarni is_large_entity(int entity_code)
6117e6ad469SVishal Kulkarni {
6127e6ad469SVishal Kulkarni 	int i;
6137e6ad469SVishal Kulkarni 
6147e6ad469SVishal Kulkarni 	for (i = 0; i < sizeof(large_entity_list) / sizeof(struct large_entity);
6157e6ad469SVishal Kulkarni 	     i++) {
6167e6ad469SVishal Kulkarni 		if (large_entity_list[i].entity_code == entity_code)
6177e6ad469SVishal Kulkarni 			return 1;
6187e6ad469SVishal Kulkarni 	}
6197e6ad469SVishal Kulkarni 	return 0;
6207e6ad469SVishal Kulkarni }
6217e6ad469SVishal Kulkarni 
6227e6ad469SVishal Kulkarni int
get_entity_hdr(void * outbuf,int i,u32 size,struct cudbg_entity_hdr ** entity_hdr)6237e6ad469SVishal Kulkarni get_entity_hdr(void *outbuf, int i, u32 size,
6247e6ad469SVishal Kulkarni 	       struct cudbg_entity_hdr **entity_hdr)
6257e6ad469SVishal Kulkarni {
6267e6ad469SVishal Kulkarni 	int rc = 0;
6277e6ad469SVishal Kulkarni 	struct cudbg_hdr *cudbg_hdr = (struct cudbg_hdr *)outbuf;
6287e6ad469SVishal Kulkarni 
6297e6ad469SVishal Kulkarni 	if (cudbg_hdr->hdr_len + (sizeof(struct cudbg_entity_hdr)*i) > size)
6307e6ad469SVishal Kulkarni 		return CUDBG_STATUS_SMALL_BUFF;
6317e6ad469SVishal Kulkarni 
6327e6ad469SVishal Kulkarni 	*entity_hdr = (struct cudbg_entity_hdr *)
6337e6ad469SVishal Kulkarni 		      ((char *)outbuf+cudbg_hdr->hdr_len +
6347e6ad469SVishal Kulkarni 		       (sizeof(struct cudbg_entity_hdr)*(i-1)));
6357e6ad469SVishal Kulkarni 	return rc;
6367e6ad469SVishal Kulkarni }
6377e6ad469SVishal Kulkarni 
6387e6ad469SVishal Kulkarni static int
collect_rss(struct cudbg_init * pdbg_init,struct cudbg_buffer * dbg_buff,struct cudbg_error * cudbg_err)6397e6ad469SVishal Kulkarni collect_rss(struct cudbg_init *pdbg_init,
6407e6ad469SVishal Kulkarni 	    struct cudbg_buffer *dbg_buff,
6417e6ad469SVishal Kulkarni 	    struct cudbg_error *cudbg_err)
6427e6ad469SVishal Kulkarni {
6437e6ad469SVishal Kulkarni 	struct adapter *padap = pdbg_init->adap;
6447e6ad469SVishal Kulkarni 	struct cudbg_buffer scratch_buff;
6457e6ad469SVishal Kulkarni 	u32 size;
6467e6ad469SVishal Kulkarni 	int rc = 0;
6477e6ad469SVishal Kulkarni 
6487e6ad469SVishal Kulkarni 	size = RSS_NENTRIES  * sizeof(u16);
6497e6ad469SVishal Kulkarni 	rc = get_scratch_buff(dbg_buff, size, &scratch_buff);
6507e6ad469SVishal Kulkarni 	if (rc)
6517e6ad469SVishal Kulkarni 		goto err;
6527e6ad469SVishal Kulkarni 
6537e6ad469SVishal Kulkarni 	rc = t4_read_rss(padap, (u16 *)scratch_buff.data);
6547e6ad469SVishal Kulkarni 	if (rc) {
6557e6ad469SVishal Kulkarni 		if (pdbg_init->verbose)
6567e6ad469SVishal Kulkarni 			pdbg_init->print(padap->dip, CE_NOTE,
6577e6ad469SVishal Kulkarni 					 "%s(), t4_read_rss failed!, rc: %d\n",
6587e6ad469SVishal Kulkarni 				 __func__, rc);
6597e6ad469SVishal Kulkarni 		cudbg_err->sys_err = rc;
6607e6ad469SVishal Kulkarni 		goto err1;
6617e6ad469SVishal Kulkarni 	}
6627e6ad469SVishal Kulkarni 
6637e6ad469SVishal Kulkarni 	rc = write_compression_hdr(&scratch_buff, dbg_buff);
6647e6ad469SVishal Kulkarni 	if (rc)
6657e6ad469SVishal Kulkarni 		goto err1;
6667e6ad469SVishal Kulkarni 
6677e6ad469SVishal Kulkarni 	rc = compress_buff(&scratch_buff, dbg_buff);
6687e6ad469SVishal Kulkarni 
6697e6ad469SVishal Kulkarni err1:
6707e6ad469SVishal Kulkarni 	release_scratch_buff(&scratch_buff, dbg_buff);
6717e6ad469SVishal Kulkarni err:
6727e6ad469SVishal Kulkarni 	return rc;
6737e6ad469SVishal Kulkarni }
6747e6ad469SVishal Kulkarni 
6757e6ad469SVishal Kulkarni static int
collect_sw_state(struct cudbg_init * pdbg_init,struct cudbg_buffer * dbg_buff,struct cudbg_error * cudbg_err)6767e6ad469SVishal Kulkarni collect_sw_state(struct cudbg_init *pdbg_init,
6777e6ad469SVishal Kulkarni 		 struct cudbg_buffer *dbg_buff,
6787e6ad469SVishal Kulkarni 		 struct cudbg_error *cudbg_err)
6797e6ad469SVishal Kulkarni {
6807e6ad469SVishal Kulkarni 	struct adapter *padap = pdbg_init->adap;
6817e6ad469SVishal Kulkarni 	struct cudbg_buffer scratch_buff;
6827e6ad469SVishal Kulkarni 	struct sw_state *swstate;
6837e6ad469SVishal Kulkarni 	u32 size;
6847e6ad469SVishal Kulkarni 	int rc = 0;
6857e6ad469SVishal Kulkarni 
6867e6ad469SVishal Kulkarni 	size = sizeof(struct sw_state);
6877e6ad469SVishal Kulkarni 
6887e6ad469SVishal Kulkarni 	rc = get_scratch_buff(dbg_buff, size, &scratch_buff);
6897e6ad469SVishal Kulkarni 	if (rc)
6907e6ad469SVishal Kulkarni 		goto err;
6917e6ad469SVishal Kulkarni 
6927e6ad469SVishal Kulkarni 	swstate = (struct sw_state *) scratch_buff.data;
6937e6ad469SVishal Kulkarni 
6947e6ad469SVishal Kulkarni 	swstate->fw_state = t4_read_reg(padap, A_PCIE_FW);
6957e6ad469SVishal Kulkarni 	snprintf((char *)swstate->caller_string, sizeof(swstate->caller_string), "%s",
6967e6ad469SVishal Kulkarni 	    "Illumos");
6977e6ad469SVishal Kulkarni 	swstate->os_type = 0;
6987e6ad469SVishal Kulkarni 
6997e6ad469SVishal Kulkarni 	rc = write_compression_hdr(&scratch_buff, dbg_buff);
7007e6ad469SVishal Kulkarni 	if (rc)
7017e6ad469SVishal Kulkarni 		goto err1;
7027e6ad469SVishal Kulkarni 
7037e6ad469SVishal Kulkarni 	rc = compress_buff(&scratch_buff, dbg_buff);
7047e6ad469SVishal Kulkarni 
7057e6ad469SVishal Kulkarni err1:
7067e6ad469SVishal Kulkarni 	release_scratch_buff(&scratch_buff, dbg_buff);
7077e6ad469SVishal Kulkarni err:
7087e6ad469SVishal Kulkarni 	return rc;
7097e6ad469SVishal Kulkarni }
7107e6ad469SVishal Kulkarni 
7117e6ad469SVishal Kulkarni static int
collect_ddp_stats(struct cudbg_init * pdbg_init,struct cudbg_buffer * dbg_buff,struct cudbg_error * cudbg_err)7127e6ad469SVishal Kulkarni collect_ddp_stats(struct cudbg_init *pdbg_init,
7137e6ad469SVishal Kulkarni 		  struct cudbg_buffer *dbg_buff,
7147e6ad469SVishal Kulkarni 		  struct cudbg_error *cudbg_err)
7157e6ad469SVishal Kulkarni {
7167e6ad469SVishal Kulkarni 	struct adapter *padap = pdbg_init->adap;
7177e6ad469SVishal Kulkarni 	struct cudbg_buffer scratch_buff;
7187e6ad469SVishal Kulkarni 	struct tp_usm_stats  *tp_usm_stats_buff;
7197e6ad469SVishal Kulkarni 	u32 size;
7207e6ad469SVishal Kulkarni 	int rc = 0;
7217e6ad469SVishal Kulkarni 
7227e6ad469SVishal Kulkarni 	size = sizeof(struct tp_usm_stats);
7237e6ad469SVishal Kulkarni 
7247e6ad469SVishal Kulkarni 	rc = get_scratch_buff(dbg_buff, size, &scratch_buff);
7257e6ad469SVishal Kulkarni 	if (rc)
7267e6ad469SVishal Kulkarni 		goto err;
7277e6ad469SVishal Kulkarni 
7287e6ad469SVishal Kulkarni 	tp_usm_stats_buff = (struct tp_usm_stats *) scratch_buff.data;
7297e6ad469SVishal Kulkarni 
7307e6ad469SVishal Kulkarni 	/* spin_lock(&padap->stats_lock);	TODO*/
7317e6ad469SVishal Kulkarni 	t4_get_usm_stats(padap, tp_usm_stats_buff, 1);
7327e6ad469SVishal Kulkarni 	/* spin_unlock(&padap->stats_lock);	TODO*/
7337e6ad469SVishal Kulkarni 
734