xref: /freebsd/sys/dev/qlnx/qlnxe/qlnx_ioctl.c (revision 217ec20885fd2a44a9bb369b8d69eb35139ffafc)
111e25f0dSDavid C Somayajulu /*
211e25f0dSDavid C Somayajulu  * Copyright (c) 2017-2018 Cavium, Inc.
311e25f0dSDavid C Somayajulu  * All rights reserved.
411e25f0dSDavid C Somayajulu  *
511e25f0dSDavid C Somayajulu  *  Redistribution and use in source and binary forms, with or without
611e25f0dSDavid C Somayajulu  *  modification, are permitted provided that the following conditions
711e25f0dSDavid C Somayajulu  *  are met:
811e25f0dSDavid C Somayajulu  *
911e25f0dSDavid C Somayajulu  *  1. Redistributions of source code must retain the above copyright
1011e25f0dSDavid C Somayajulu  *     notice, this list of conditions and the following disclaimer.
1111e25f0dSDavid C Somayajulu  *  2. Redistributions in binary form must reproduce the above copyright
1211e25f0dSDavid C Somayajulu  *     notice, this list of conditions and the following disclaimer in the
1311e25f0dSDavid C Somayajulu  *     documentation and/or other materials provided with the distribution.
1411e25f0dSDavid C Somayajulu  *
1511e25f0dSDavid C Somayajulu  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1611e25f0dSDavid C Somayajulu  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1711e25f0dSDavid C Somayajulu  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1811e25f0dSDavid C Somayajulu  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
1911e25f0dSDavid C Somayajulu  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2011e25f0dSDavid C Somayajulu  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2111e25f0dSDavid C Somayajulu  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2211e25f0dSDavid C Somayajulu  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2311e25f0dSDavid C Somayajulu  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2411e25f0dSDavid C Somayajulu  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2511e25f0dSDavid C Somayajulu  *  POSSIBILITY OF SUCH DAMAGE.
2611e25f0dSDavid C Somayajulu  */
2711e25f0dSDavid C Somayajulu 
2811e25f0dSDavid C Somayajulu 
2911e25f0dSDavid C Somayajulu /*
3011e25f0dSDavid C Somayajulu  * File: qlnx_ioctl.c
3111e25f0dSDavid C Somayajulu  * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
3211e25f0dSDavid C Somayajulu  */
3311e25f0dSDavid C Somayajulu 
3411e25f0dSDavid C Somayajulu #include <sys/cdefs.h>
3511e25f0dSDavid C Somayajulu __FBSDID("$FreeBSD$");
3611e25f0dSDavid C Somayajulu 
3711e25f0dSDavid C Somayajulu #include "qlnx_os.h"
3811e25f0dSDavid C Somayajulu #include "bcm_osal.h"
3911e25f0dSDavid C Somayajulu 
4011e25f0dSDavid C Somayajulu #include "reg_addr.h"
4111e25f0dSDavid C Somayajulu #include "ecore_gtt_reg_addr.h"
4211e25f0dSDavid C Somayajulu #include "ecore.h"
4311e25f0dSDavid C Somayajulu #include "ecore_chain.h"
4411e25f0dSDavid C Somayajulu #include "ecore_status.h"
4511e25f0dSDavid C Somayajulu #include "ecore_hw.h"
4611e25f0dSDavid C Somayajulu #include "ecore_rt_defs.h"
4711e25f0dSDavid C Somayajulu #include "ecore_init_ops.h"
4811e25f0dSDavid C Somayajulu #include "ecore_int.h"
4911e25f0dSDavid C Somayajulu #include "ecore_cxt.h"
5011e25f0dSDavid C Somayajulu #include "ecore_spq.h"
5111e25f0dSDavid C Somayajulu #include "ecore_init_fw_funcs.h"
5211e25f0dSDavid C Somayajulu #include "ecore_sp_commands.h"
5311e25f0dSDavid C Somayajulu #include "ecore_dev_api.h"
5411e25f0dSDavid C Somayajulu #include "ecore_l2_api.h"
5511e25f0dSDavid C Somayajulu #include "ecore_mcp.h"
5611e25f0dSDavid C Somayajulu #include "ecore_hw_defs.h"
5711e25f0dSDavid C Somayajulu #include "mcp_public.h"
5811e25f0dSDavid C Somayajulu #include "ecore_iro.h"
5911e25f0dSDavid C Somayajulu #include "nvm_cfg.h"
6011e25f0dSDavid C Somayajulu #include "ecore_dev_api.h"
6111e25f0dSDavid C Somayajulu #include "ecore_dbg_fw_funcs.h"
62*217ec208SDavid C Somayajulu #include "ecore_dcbx_api.h"
6311e25f0dSDavid C Somayajulu 
6411e25f0dSDavid C Somayajulu #include "qlnx_ioctl.h"
6511e25f0dSDavid C Somayajulu #include "qlnx_def.h"
6611e25f0dSDavid C Somayajulu #include "qlnx_ver.h"
6711e25f0dSDavid C Somayajulu #include <sys/smp.h>
6811e25f0dSDavid C Somayajulu 
6911e25f0dSDavid C Somayajulu 
7011e25f0dSDavid C Somayajulu static int qlnx_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
7111e25f0dSDavid C Somayajulu                 struct thread *td);
7211e25f0dSDavid C Somayajulu 
7311e25f0dSDavid C Somayajulu static struct cdevsw qlnx_cdevsw = {
7411e25f0dSDavid C Somayajulu         .d_version = D_VERSION,
7511e25f0dSDavid C Somayajulu         .d_ioctl = qlnx_eioctl,
7611e25f0dSDavid C Somayajulu         .d_name = "qlnxioctl",
7711e25f0dSDavid C Somayajulu };
7811e25f0dSDavid C Somayajulu 
7911e25f0dSDavid C Somayajulu int
8011e25f0dSDavid C Somayajulu qlnx_make_cdev(qlnx_host_t *ha)
8111e25f0dSDavid C Somayajulu {
8211e25f0dSDavid C Somayajulu 	ha->ioctl_dev = make_dev(&qlnx_cdevsw,
8311e25f0dSDavid C Somayajulu 				ha->ifp->if_dunit,
8411e25f0dSDavid C Somayajulu 				UID_ROOT,
8511e25f0dSDavid C Somayajulu 				GID_WHEEL,
8611e25f0dSDavid C Somayajulu 				0600,
8711e25f0dSDavid C Somayajulu 				"%s",
8811e25f0dSDavid C Somayajulu 				if_name(ha->ifp));
8911e25f0dSDavid C Somayajulu 
9011e25f0dSDavid C Somayajulu 	if (ha->ioctl_dev == NULL)
9111e25f0dSDavid C Somayajulu 		return (-1);
9211e25f0dSDavid C Somayajulu 
9311e25f0dSDavid C Somayajulu 	ha->ioctl_dev->si_drv1 = ha;
9411e25f0dSDavid C Somayajulu 
9511e25f0dSDavid C Somayajulu 	return (0);
9611e25f0dSDavid C Somayajulu }
9711e25f0dSDavid C Somayajulu 
9811e25f0dSDavid C Somayajulu void
9911e25f0dSDavid C Somayajulu qlnx_del_cdev(qlnx_host_t *ha)
10011e25f0dSDavid C Somayajulu {
10111e25f0dSDavid C Somayajulu 	if (ha->ioctl_dev != NULL)
10211e25f0dSDavid C Somayajulu 		destroy_dev(ha->ioctl_dev);
10311e25f0dSDavid C Somayajulu 	return;
10411e25f0dSDavid C Somayajulu }
10511e25f0dSDavid C Somayajulu 
10611e25f0dSDavid C Somayajulu int
10711e25f0dSDavid C Somayajulu qlnx_grc_dump(qlnx_host_t *ha, uint32_t *num_dumped_dwords, int hwfn_index)
10811e25f0dSDavid C Somayajulu {
10911e25f0dSDavid C Somayajulu 	int rval = EINVAL;
11011e25f0dSDavid C Somayajulu 	struct ecore_hwfn *p_hwfn;
11111e25f0dSDavid C Somayajulu 	struct ecore_ptt *p_ptt;
11211e25f0dSDavid C Somayajulu 
11311e25f0dSDavid C Somayajulu 	if (ha->grcdump_dwords[hwfn_index]) {
11411e25f0dSDavid C Somayajulu 		/* the grcdump is already available */
11511e25f0dSDavid C Somayajulu 		*num_dumped_dwords = ha->grcdump_dwords[hwfn_index];
11611e25f0dSDavid C Somayajulu 		return (0);
11711e25f0dSDavid C Somayajulu 	}
11811e25f0dSDavid C Somayajulu 
11911e25f0dSDavid C Somayajulu 	ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver());
12011e25f0dSDavid C Somayajulu 
12111e25f0dSDavid C Somayajulu 	p_hwfn = &ha->cdev.hwfns[hwfn_index];
12211e25f0dSDavid C Somayajulu 	p_ptt = ecore_ptt_acquire(p_hwfn);
12311e25f0dSDavid C Somayajulu 
12411e25f0dSDavid C Somayajulu 	if (!p_ptt) {
1257a377fbeSDavid C Somayajulu 		QL_DPRINT1(ha,"ecore_ptt_acquire failed\n");
12611e25f0dSDavid C Somayajulu 		return (rval);
12711e25f0dSDavid C Somayajulu 	}
12811e25f0dSDavid C Somayajulu 
12911e25f0dSDavid C Somayajulu 	if ((rval = ecore_dbg_grc_dump(p_hwfn, p_ptt,
13011e25f0dSDavid C Somayajulu 			ha->grcdump[hwfn_index],
13111e25f0dSDavid C Somayajulu 			(ha->grcdump_size[hwfn_index] >> 2),
13211e25f0dSDavid C Somayajulu 			num_dumped_dwords)) == DBG_STATUS_OK) {
13311e25f0dSDavid C Somayajulu 	 	rval = 0;
13411e25f0dSDavid C Somayajulu 		ha->grcdump_taken = 1;
13511e25f0dSDavid C Somayajulu 	} else
1367a377fbeSDavid C Somayajulu 		QL_DPRINT1(ha,"ecore_dbg_grc_dump failed [%d, 0x%x]\n",
1377a377fbeSDavid C Somayajulu 			   hwfn_index, rval);
13811e25f0dSDavid C Somayajulu 
13911e25f0dSDavid C Somayajulu 	ecore_ptt_release(p_hwfn, p_ptt);
14011e25f0dSDavid C Somayajulu 
14111e25f0dSDavid C Somayajulu 	return (rval);
14211e25f0dSDavid C Somayajulu }
14311e25f0dSDavid C Somayajulu 
14411e25f0dSDavid C Somayajulu static void
14511e25f0dSDavid C Somayajulu qlnx_get_grc_dump_size(qlnx_host_t *ha, qlnx_grcdump_t *grcdump)
14611e25f0dSDavid C Somayajulu {
14711e25f0dSDavid C Somayajulu 	int i;
14811e25f0dSDavid C Somayajulu 
14911e25f0dSDavid C Somayajulu 	grcdump->pci_func = ha->pci_func;
15011e25f0dSDavid C Somayajulu 
15111e25f0dSDavid C Somayajulu 	for (i = 0; i < ha->cdev.num_hwfns; i++)
15211e25f0dSDavid C Somayajulu 		grcdump->grcdump_size[i] = ha->grcdump_size[i];
15311e25f0dSDavid C Somayajulu 
15411e25f0dSDavid C Somayajulu 	return;
15511e25f0dSDavid C Somayajulu }
15611e25f0dSDavid C Somayajulu 
15711e25f0dSDavid C Somayajulu static int
15811e25f0dSDavid C Somayajulu qlnx_get_grc_dump(qlnx_host_t *ha, qlnx_grcdump_t *grcdump)
15911e25f0dSDavid C Somayajulu {
16011e25f0dSDavid C Somayajulu 	int		i;
16111e25f0dSDavid C Somayajulu 	int		rval = 0;
16211e25f0dSDavid C Somayajulu 	uint32_t	dwords = 0;
16311e25f0dSDavid C Somayajulu 
16411e25f0dSDavid C Somayajulu 	grcdump->pci_func = ha->pci_func;
16511e25f0dSDavid C Somayajulu 
16611e25f0dSDavid C Somayajulu 	for (i = 0; i < ha->cdev.num_hwfns; i++) {
16711e25f0dSDavid C Somayajulu 
16811e25f0dSDavid C Somayajulu 		if ((ha->grcdump[i] == NULL) || (grcdump->grcdump[i] == NULL) ||
16911e25f0dSDavid C Somayajulu 			(grcdump->grcdump_size[i] < ha->grcdump_size[i]))
17011e25f0dSDavid C Somayajulu 			return (EINVAL);
17111e25f0dSDavid C Somayajulu 
17211e25f0dSDavid C Somayajulu 		rval = qlnx_grc_dump(ha, &dwords, i);
17311e25f0dSDavid C Somayajulu 
17411e25f0dSDavid C Somayajulu 		if (rval)
17511e25f0dSDavid C Somayajulu 			break;
17611e25f0dSDavid C Somayajulu 
17711e25f0dSDavid C Somayajulu 		grcdump->grcdump_dwords[i] = dwords;
17811e25f0dSDavid C Somayajulu 
1797a377fbeSDavid C Somayajulu 		QL_DPRINT1(ha,"grcdump_dwords[%d] = 0x%x\n", i, dwords);
18011e25f0dSDavid C Somayajulu 
18111e25f0dSDavid C Somayajulu 		rval = copyout(ha->grcdump[i], grcdump->grcdump[i],
18211e25f0dSDavid C Somayajulu 				ha->grcdump_size[i]);
18311e25f0dSDavid C Somayajulu 
18411e25f0dSDavid C Somayajulu 		if (rval)
18511e25f0dSDavid C Somayajulu 			break;
18611e25f0dSDavid C Somayajulu 
18711e25f0dSDavid C Somayajulu 		ha->grcdump_dwords[i] = 0;
18811e25f0dSDavid C Somayajulu 	}
18911e25f0dSDavid C Somayajulu 
19011e25f0dSDavid C Somayajulu 	ha->grcdump_taken = 0;
19111e25f0dSDavid C Somayajulu 
19211e25f0dSDavid C Somayajulu 	return (rval);
19311e25f0dSDavid C Somayajulu }
19411e25f0dSDavid C Somayajulu 
19511e25f0dSDavid C Somayajulu int
19611e25f0dSDavid C Somayajulu qlnx_idle_chk(qlnx_host_t *ha, uint32_t *num_dumped_dwords, int hwfn_index)
19711e25f0dSDavid C Somayajulu {
19811e25f0dSDavid C Somayajulu 	int rval = EINVAL;
19911e25f0dSDavid C Somayajulu 	struct ecore_hwfn *p_hwfn;
20011e25f0dSDavid C Somayajulu 	struct ecore_ptt *p_ptt;
20111e25f0dSDavid C Somayajulu 
20211e25f0dSDavid C Somayajulu 	if (ha->idle_chk_dwords[hwfn_index]) {
20311e25f0dSDavid C Somayajulu 		/* the idle check is already available */
20411e25f0dSDavid C Somayajulu 		*num_dumped_dwords = ha->idle_chk_dwords[hwfn_index];
20511e25f0dSDavid C Somayajulu 		return (0);
20611e25f0dSDavid C Somayajulu 	}
20711e25f0dSDavid C Somayajulu 
20811e25f0dSDavid C Somayajulu 	ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver());
20911e25f0dSDavid C Somayajulu 
21011e25f0dSDavid C Somayajulu 	p_hwfn = &ha->cdev.hwfns[hwfn_index];
21111e25f0dSDavid C Somayajulu 	p_ptt = ecore_ptt_acquire(p_hwfn);
21211e25f0dSDavid C Somayajulu 
21311e25f0dSDavid C Somayajulu 	if (!p_ptt) {
2147a377fbeSDavid C Somayajulu 		QL_DPRINT1(ha,"ecore_ptt_acquire failed\n");
21511e25f0dSDavid C Somayajulu 		return (rval);
21611e25f0dSDavid C Somayajulu 	}
21711e25f0dSDavid C Somayajulu 
21811e25f0dSDavid C Somayajulu 	if ((rval = ecore_dbg_idle_chk_dump(p_hwfn, p_ptt,
21911e25f0dSDavid C Somayajulu 			ha->idle_chk[hwfn_index],
22011e25f0dSDavid C Somayajulu 			(ha->idle_chk_size[hwfn_index] >> 2),
22111e25f0dSDavid C Somayajulu 			num_dumped_dwords)) == DBG_STATUS_OK) {
22211e25f0dSDavid C Somayajulu 	 	rval = 0;
22311e25f0dSDavid C Somayajulu 		ha->idle_chk_taken = 1;
22411e25f0dSDavid C Somayajulu 	} else
2257a377fbeSDavid C Somayajulu 		QL_DPRINT1(ha,"ecore_dbg_idle_chk_dump failed [%d, 0x%x]\n",
2267a377fbeSDavid C Somayajulu 			   hwfn_index, rval);
22711e25f0dSDavid C Somayajulu 
22811e25f0dSDavid C Somayajulu 	ecore_ptt_release(p_hwfn, p_ptt);
22911e25f0dSDavid C Somayajulu 
23011e25f0dSDavid C Somayajulu 	return (rval);
23111e25f0dSDavid C Somayajulu }
23211e25f0dSDavid C Somayajulu 
23311e25f0dSDavid C Somayajulu static void
23411e25f0dSDavid C Somayajulu qlnx_get_idle_chk_size(qlnx_host_t *ha, qlnx_idle_chk_t *idle_chk)
23511e25f0dSDavid C Somayajulu {
23611e25f0dSDavid C Somayajulu 	int i;
23711e25f0dSDavid C Somayajulu 
23811e25f0dSDavid C Somayajulu 	idle_chk->pci_func = ha->pci_func;
23911e25f0dSDavid C Somayajulu 
24011e25f0dSDavid C Somayajulu 	for (i = 0; i < ha->cdev.num_hwfns; i++)
24111e25f0dSDavid C Somayajulu 		idle_chk->idle_chk_size[i] = ha->idle_chk_size[i];
24211e25f0dSDavid C Somayajulu 
24311e25f0dSDavid C Somayajulu 	return;
24411e25f0dSDavid C Somayajulu }
24511e25f0dSDavid C Somayajulu 
24611e25f0dSDavid C Somayajulu static int
24711e25f0dSDavid C Somayajulu qlnx_get_idle_chk(qlnx_host_t *ha, qlnx_idle_chk_t *idle_chk)
24811e25f0dSDavid C Somayajulu {
24911e25f0dSDavid C Somayajulu 	int		i;
25011e25f0dSDavid C Somayajulu 	int		rval = 0;
25111e25f0dSDavid C Somayajulu 	uint32_t	dwords = 0;
25211e25f0dSDavid C Somayajulu 
25311e25f0dSDavid C Somayajulu 	idle_chk->pci_func = ha->pci_func;
25411e25f0dSDavid C Somayajulu 
25511e25f0dSDavid C Somayajulu 	for (i = 0; i < ha->cdev.num_hwfns; i++) {
25611e25f0dSDavid C Somayajulu 
25711e25f0dSDavid C Somayajulu 		if ((ha->idle_chk[i] == NULL) ||
25811e25f0dSDavid C Somayajulu 				(idle_chk->idle_chk[i] == NULL) ||
25911e25f0dSDavid C Somayajulu 				(idle_chk->idle_chk_size[i] <
26011e25f0dSDavid C Somayajulu 					ha->idle_chk_size[i]))
26111e25f0dSDavid C Somayajulu 			return (EINVAL);
26211e25f0dSDavid C Somayajulu 
26311e25f0dSDavid C Somayajulu 		rval = qlnx_idle_chk(ha, &dwords, i);
26411e25f0dSDavid C Somayajulu 
26511e25f0dSDavid C Somayajulu 		if (rval)
26611e25f0dSDavid C Somayajulu 			break;
26711e25f0dSDavid C Somayajulu 
26811e25f0dSDavid C Somayajulu 		idle_chk->idle_chk_dwords[i] = dwords;
26911e25f0dSDavid C Somayajulu 
2707a377fbeSDavid C Somayajulu 		QL_DPRINT1(ha,"idle_chk_dwords[%d] = 0x%x\n", i, dwords);
27111e25f0dSDavid C Somayajulu 
27211e25f0dSDavid C Somayajulu                	rval = copyout(ha->idle_chk[i], idle_chk->idle_chk[i],
27311e25f0dSDavid C Somayajulu 				ha->idle_chk_size[i]);
27411e25f0dSDavid C Somayajulu 
27511e25f0dSDavid C Somayajulu 		if (rval)
27611e25f0dSDavid C Somayajulu 			break;
27711e25f0dSDavid C Somayajulu 
27811e25f0dSDavid C Somayajulu 		ha->idle_chk_dwords[i] = 0;
27911e25f0dSDavid C Somayajulu 	}
28011e25f0dSDavid C Somayajulu 	ha->idle_chk_taken = 0;
28111e25f0dSDavid C Somayajulu 
28211e25f0dSDavid C Somayajulu 	return (rval);
28311e25f0dSDavid C Somayajulu }
28411e25f0dSDavid C Somayajulu 
28511e25f0dSDavid C Somayajulu static uint32_t
28611e25f0dSDavid C Somayajulu qlnx_get_trace_cmd_size(qlnx_host_t *ha, int hwfn_index, uint16_t cmd)
28711e25f0dSDavid C Somayajulu {
28811e25f0dSDavid C Somayajulu         int rval = -1;
28911e25f0dSDavid C Somayajulu         struct ecore_hwfn *p_hwfn;
29011e25f0dSDavid C Somayajulu         struct ecore_ptt *p_ptt;
29111e25f0dSDavid C Somayajulu 	uint32_t num_dwords = 0;
29211e25f0dSDavid C Somayajulu 
29311e25f0dSDavid C Somayajulu         p_hwfn = &ha->cdev.hwfns[hwfn_index];
29411e25f0dSDavid C Somayajulu         p_ptt = ecore_ptt_acquire(p_hwfn);
29511e25f0dSDavid C Somayajulu 
29611e25f0dSDavid C Somayajulu         if (!p_ptt) {
2977a377fbeSDavid C Somayajulu                 QL_DPRINT1(ha, "ecore_ptt_acquire [%d, 0x%x]failed\n",
2987a377fbeSDavid C Somayajulu                            hwfn_index, cmd);
29911e25f0dSDavid C Somayajulu                 return (0);
30011e25f0dSDavid C Somayajulu         }
30111e25f0dSDavid C Somayajulu 
30211e25f0dSDavid C Somayajulu 	switch (cmd) {
30311e25f0dSDavid C Somayajulu 
30411e25f0dSDavid C Somayajulu 	case QLNX_MCP_TRACE:
30511e25f0dSDavid C Somayajulu         	rval = ecore_dbg_mcp_trace_get_dump_buf_size(p_hwfn,
30611e25f0dSDavid C Somayajulu 				p_ptt, &num_dwords);
30711e25f0dSDavid C Somayajulu 		break;
30811e25f0dSDavid C Somayajulu 
30911e25f0dSDavid C Somayajulu 	case QLNX_REG_FIFO:
31011e25f0dSDavid C Somayajulu         	rval = ecore_dbg_reg_fifo_get_dump_buf_size(p_hwfn,
31111e25f0dSDavid C Somayajulu 				p_ptt, &num_dwords);
31211e25f0dSDavid C Somayajulu 		break;
31311e25f0dSDavid C Somayajulu 
31411e25f0dSDavid C Somayajulu 	case QLNX_IGU_FIFO:
31511e25f0dSDavid C Somayajulu         	rval = ecore_dbg_igu_fifo_get_dump_buf_size(p_hwfn,
31611e25f0dSDavid C Somayajulu 				p_ptt, &num_dwords);
31711e25f0dSDavid C Somayajulu 		break;
31811e25f0dSDavid C Somayajulu 
31911e25f0dSDavid C Somayajulu 	case QLNX_PROTECTION_OVERRIDE:
32011e25f0dSDavid C Somayajulu         	rval = ecore_dbg_protection_override_get_dump_buf_size(p_hwfn,
32111e25f0dSDavid C Somayajulu 				p_ptt, &num_dwords);
32211e25f0dSDavid C Somayajulu 		break;
32311e25f0dSDavid C Somayajulu 
32411e25f0dSDavid C Somayajulu 	case QLNX_FW_ASSERTS:
32511e25f0dSDavid C Somayajulu         	rval = ecore_dbg_fw_asserts_get_dump_buf_size(p_hwfn,
32611e25f0dSDavid C Somayajulu 				p_ptt, &num_dwords);
32711e25f0dSDavid C Somayajulu 		break;
32811e25f0dSDavid C Somayajulu 	}
32911e25f0dSDavid C Somayajulu 
33011e25f0dSDavid C Somayajulu         if (rval != DBG_STATUS_OK) {
3317a377fbeSDavid C Somayajulu                 QL_DPRINT1(ha,"cmd = 0x%x failed [0x%x]\n", cmd, rval);
33211e25f0dSDavid C Somayajulu 		num_dwords = 0;
33311e25f0dSDavid C Somayajulu         }
33411e25f0dSDavid C Somayajulu 
33511e25f0dSDavid C Somayajulu         ecore_ptt_release(p_hwfn, p_ptt);
33611e25f0dSDavid C Somayajulu 
33711e25f0dSDavid C Somayajulu         return ((num_dwords * sizeof (uint32_t)));
33811e25f0dSDavid C Somayajulu }
33911e25f0dSDavid C Somayajulu 
34011e25f0dSDavid C Somayajulu static void
34111e25f0dSDavid C Somayajulu qlnx_get_trace_size(qlnx_host_t *ha, qlnx_trace_t *trace)
34211e25f0dSDavid C Somayajulu {
34311e25f0dSDavid C Somayajulu 	int i;
34411e25f0dSDavid C Somayajulu 
34511e25f0dSDavid C Somayajulu 	trace->pci_func = ha->pci_func;
34611e25f0dSDavid C Somayajulu 
34711e25f0dSDavid C Somayajulu 	for (i = 0; i < ha->cdev.num_hwfns; i++) {
34811e25f0dSDavid C Somayajulu 		trace->size[i] = qlnx_get_trace_cmd_size(ha, i, trace->cmd);
34911e25f0dSDavid C Somayajulu 	}
35011e25f0dSDavid C Somayajulu 
35111e25f0dSDavid C Somayajulu 	return;
35211e25f0dSDavid C Somayajulu }
35311e25f0dSDavid C Somayajulu 
35411e25f0dSDavid C Somayajulu static int
35511e25f0dSDavid C Somayajulu qlnx_get_trace(qlnx_host_t *ha, int hwfn_index, qlnx_trace_t *trace)
35611e25f0dSDavid C Somayajulu {
35711e25f0dSDavid C Somayajulu         int rval = -1;
35811e25f0dSDavid C Somayajulu         struct ecore_hwfn *p_hwfn;
35911e25f0dSDavid C Somayajulu         struct ecore_ptt *p_ptt;
36011e25f0dSDavid C Somayajulu 	uint32_t num_dwords = 0;
36111e25f0dSDavid C Somayajulu 	void *buffer;
36211e25f0dSDavid C Somayajulu 
36311e25f0dSDavid C Somayajulu 	buffer = qlnx_zalloc(trace->size[hwfn_index]);
36411e25f0dSDavid C Somayajulu 	if (buffer == NULL) {
3657a377fbeSDavid C Somayajulu                 QL_DPRINT1(ha,"qlnx_zalloc [%d, 0x%x]failed\n",
3667a377fbeSDavid C Somayajulu                            hwfn_index, trace->cmd);
36711e25f0dSDavid C Somayajulu                 return (ENXIO);
36811e25f0dSDavid C Somayajulu 	}
36911e25f0dSDavid C Somayajulu 	ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver());
37011e25f0dSDavid C Somayajulu 
37111e25f0dSDavid C Somayajulu         p_hwfn = &ha->cdev.hwfns[hwfn_index];
37211e25f0dSDavid C Somayajulu         p_ptt = ecore_ptt_acquire(p_hwfn);
37311e25f0dSDavid C Somayajulu 
37411e25f0dSDavid C Somayajulu         if (!p_ptt) {
3757a377fbeSDavid C Somayajulu                 QL_DPRINT1(ha, "ecore_ptt_acquire [%d, 0x%x]failed\n",
3767a377fbeSDavid C Somayajulu                            hwfn_index, trace->cmd);
37711e25f0dSDavid C Somayajulu                 return (ENXIO);
37811e25f0dSDavid C Somayajulu         }
37911e25f0dSDavid C Somayajulu 
38011e25f0dSDavid C Somayajulu 	switch (trace->cmd) {
38111e25f0dSDavid C Somayajulu 
38211e25f0dSDavid C Somayajulu 	case QLNX_MCP_TRACE:
38311e25f0dSDavid C Somayajulu         	rval = ecore_dbg_mcp_trace_dump(p_hwfn, p_ptt,
38411e25f0dSDavid C Somayajulu 				buffer, (trace->size[hwfn_index] >> 2),
38511e25f0dSDavid C Somayajulu 				&num_dwords);
38611e25f0dSDavid C Somayajulu 		break;
38711e25f0dSDavid C Somayajulu 
38811e25f0dSDavid C Somayajulu 	case QLNX_REG_FIFO:
38911e25f0dSDavid C Somayajulu         	rval = ecore_dbg_reg_fifo_dump(p_hwfn, p_ptt,
39011e25f0dSDavid C Somayajulu 				buffer, (trace->size[hwfn_index] >> 2),
39111e25f0dSDavid C Somayajulu 				&num_dwords);
39211e25f0dSDavid C Somayajulu 		break;
39311e25f0dSDavid C Somayajulu 
39411e25f0dSDavid C Somayajulu 	case QLNX_IGU_FIFO:
39511e25f0dSDavid C Somayajulu         	rval = ecore_dbg_igu_fifo_dump(p_hwfn, p_ptt,
39611e25f0dSDavid C Somayajulu 				buffer, (trace->size[hwfn_index] >> 2),
39711e25f0dSDavid C Somayajulu 				&num_dwords);
39811e25f0dSDavid C Somayajulu 		break;
39911e25f0dSDavid C Somayajulu 
40011e25f0dSDavid C Somayajulu 	case QLNX_PROTECTION_OVERRIDE:
40111e25f0dSDavid C Somayajulu         	rval = ecore_dbg_protection_override_dump(p_hwfn, p_ptt,
40211e25f0dSDavid C Somayajulu 				buffer, (trace->size[hwfn_index] >> 2),
40311e25f0dSDavid C Somayajulu 				&num_dwords);
40411e25f0dSDavid C Somayajulu 		break;
40511e25f0dSDavid C Somayajulu 
40611e25f0dSDavid C Somayajulu 	case QLNX_FW_ASSERTS:
40711e25f0dSDavid C Somayajulu         	rval = ecore_dbg_fw_asserts_dump(p_hwfn, p_ptt,
40811e25f0dSDavid C Somayajulu 				buffer, (trace->size[hwfn_index] >> 2),
40911e25f0dSDavid C Somayajulu 				&num_dwords);
41011e25f0dSDavid C Somayajulu 		break;
41111e25f0dSDavid C Somayajulu 	}
41211e25f0dSDavid C Somayajulu 
41311e25f0dSDavid C Somayajulu         if (rval != DBG_STATUS_OK) {
4147a377fbeSDavid C Somayajulu                 QL_DPRINT1(ha,"cmd = 0x%x failed [0x%x]\n", trace->cmd, rval);
41511e25f0dSDavid C Somayajulu 		num_dwords = 0;
41611e25f0dSDavid C Somayajulu         }
41711e25f0dSDavid C Somayajulu 
41811e25f0dSDavid C Somayajulu         ecore_ptt_release(p_hwfn, p_ptt);
41911e25f0dSDavid C Somayajulu 
42011e25f0dSDavid C Somayajulu 	trace->dwords[hwfn_index] = num_dwords;
42111e25f0dSDavid C Somayajulu 
42211e25f0dSDavid C Somayajulu 	if (num_dwords) {
42311e25f0dSDavid C Somayajulu                	rval = copyout(buffer, trace->buffer[hwfn_index],
42411e25f0dSDavid C Somayajulu 				(num_dwords << 2));
42511e25f0dSDavid C Somayajulu 	}
42611e25f0dSDavid C Somayajulu 
42711e25f0dSDavid C Somayajulu         return (rval);
42811e25f0dSDavid C Somayajulu }
42911e25f0dSDavid C Somayajulu 
43011e25f0dSDavid C Somayajulu static int
43111e25f0dSDavid C Somayajulu qlnx_reg_rd_wr(qlnx_host_t *ha, qlnx_reg_rd_wr_t *reg_rd_wr)
43211e25f0dSDavid C Somayajulu {
43311e25f0dSDavid C Somayajulu 	int			rval = 0;
43411e25f0dSDavid C Somayajulu 	struct ecore_hwfn	*p_hwfn;
43511e25f0dSDavid C Somayajulu 
43611e25f0dSDavid C Somayajulu 	if (reg_rd_wr->hwfn_index >= QLNX_MAX_HW_FUNCS) {
43711e25f0dSDavid C Somayajulu 		return (EINVAL);
43811e25f0dSDavid C Somayajulu 	}
43911e25f0dSDavid C Somayajulu 
44011e25f0dSDavid C Somayajulu 	p_hwfn = &ha->cdev.hwfns[reg_rd_wr->hwfn_index];
44111e25f0dSDavid C Somayajulu 
44211e25f0dSDavid C Somayajulu 	switch (reg_rd_wr->cmd) {
44311e25f0dSDavid C Somayajulu 
44411e25f0dSDavid C Somayajulu 		case QLNX_REG_READ_CMD:
44511e25f0dSDavid C Somayajulu 			if (reg_rd_wr->access_type == QLNX_REG_ACCESS_DIRECT) {
44611e25f0dSDavid C Somayajulu 				reg_rd_wr->val = qlnx_reg_rd32(p_hwfn,
44711e25f0dSDavid C Somayajulu 							reg_rd_wr->addr);
44811e25f0dSDavid C Somayajulu 			}
44911e25f0dSDavid C Somayajulu 			break;
45011e25f0dSDavid C Somayajulu 
45111e25f0dSDavid C Somayajulu 		case QLNX_REG_WRITE_CMD:
45211e25f0dSDavid C Somayajulu 			if (reg_rd_wr->access_type == QLNX_REG_ACCESS_DIRECT) {
45311e25f0dSDavid C Somayajulu 				qlnx_reg_wr32(p_hwfn, reg_rd_wr->addr,
45411e25f0dSDavid C Somayajulu 					reg_rd_wr->val);
45511e25f0dSDavid C Somayajulu 			}
45611e25f0dSDavid C Somayajulu 			break;
45711e25f0dSDavid C Somayajulu 
45811e25f0dSDavid C Somayajulu 		default:
45911e25f0dSDavid C Somayajulu 			rval = EINVAL;
46011e25f0dSDavid C Somayajulu 			break;
46111e25f0dSDavid C Somayajulu 	}
46211e25f0dSDavid C Somayajulu 
46311e25f0dSDavid C Somayajulu 	return (rval);
46411e25f0dSDavid C Somayajulu }
46511e25f0dSDavid C Somayajulu 
46611e25f0dSDavid C Somayajulu static int
46711e25f0dSDavid C Somayajulu qlnx_rd_wr_pci_config(qlnx_host_t *ha, qlnx_pcicfg_rd_wr_t *pci_cfg_rd_wr)
46811e25f0dSDavid C Somayajulu {
46911e25f0dSDavid C Somayajulu 	int rval = 0;
47011e25f0dSDavid C Somayajulu 
47111e25f0dSDavid C Somayajulu 	switch (pci_cfg_rd_wr->cmd) {
47211e25f0dSDavid C Somayajulu 
47311e25f0dSDavid C Somayajulu 		case QLNX_PCICFG_READ:
47411e25f0dSDavid C Somayajulu 			pci_cfg_rd_wr->val = pci_read_config(ha->pci_dev,
47511e25f0dSDavid C Somayajulu 						pci_cfg_rd_wr->reg,
47611e25f0dSDavid C Somayajulu 						pci_cfg_rd_wr->width);
47711e25f0dSDavid C Somayajulu 			break;
47811e25f0dSDavid C Somayajulu 
47911e25f0dSDavid C Somayajulu 		case QLNX_PCICFG_WRITE:
48011e25f0dSDavid C Somayajulu 			pci_write_config(ha->pci_dev, pci_cfg_rd_wr->reg,
48111e25f0dSDavid C Somayajulu 				pci_cfg_rd_wr->val, pci_cfg_rd_wr->width);
48211e25f0dSDavid C Somayajulu 			break;
48311e25f0dSDavid C Somayajulu 
48411e25f0dSDavid C Somayajulu 		default:
48511e25f0dSDavid C Somayajulu 			rval = EINVAL;
48611e25f0dSDavid C Somayajulu 			break;
48711e25f0dSDavid C Somayajulu 	}
48811e25f0dSDavid C Somayajulu 
48911e25f0dSDavid C Somayajulu 	return (rval);
49011e25f0dSDavid C Somayajulu }
49111e25f0dSDavid C Somayajulu 
49211e25f0dSDavid C Somayajulu static void
49311e25f0dSDavid C Somayajulu qlnx_mac_addr(qlnx_host_t *ha, qlnx_perm_mac_addr_t *mac_addr)
49411e25f0dSDavid C Somayajulu {
49511e25f0dSDavid C Somayajulu 	bzero(mac_addr->addr, sizeof(mac_addr->addr));
49611e25f0dSDavid C Somayajulu 	snprintf(mac_addr->addr, sizeof(mac_addr->addr),
49711e25f0dSDavid C Somayajulu 		"%02x:%02x:%02x:%02x:%02x:%02x",
49811e25f0dSDavid C Somayajulu 		ha->primary_mac[0], ha->primary_mac[1], ha->primary_mac[2],
49911e25f0dSDavid C Somayajulu 		ha->primary_mac[3], ha->primary_mac[4], ha->primary_mac[5]);
50011e25f0dSDavid C Somayajulu 
50111e25f0dSDavid C Somayajulu 	return;
50211e25f0dSDavid C Somayajulu }
50311e25f0dSDavid C Somayajulu 
50411e25f0dSDavid C Somayajulu static int
50511e25f0dSDavid C Somayajulu qlnx_get_regs(qlnx_host_t *ha, qlnx_get_regs_t *regs)
50611e25f0dSDavid C Somayajulu {
50711e25f0dSDavid C Somayajulu 	int		i;
50811e25f0dSDavid C Somayajulu 	int		rval = 0;
50911e25f0dSDavid C Somayajulu 	uint32_t	dwords = 0;
51011e25f0dSDavid C Somayajulu 	uint8_t		*outb;
51111e25f0dSDavid C Somayajulu 
51211e25f0dSDavid C Somayajulu 	regs->reg_buf_len = 0;
51311e25f0dSDavid C Somayajulu 	outb = regs->reg_buf;
51411e25f0dSDavid C Somayajulu 
51511e25f0dSDavid C Somayajulu 	for (i = 0; i < ha->cdev.num_hwfns; i++) {
51611e25f0dSDavid C Somayajulu 
51711e25f0dSDavid C Somayajulu 		rval = qlnx_grc_dump(ha, &dwords, i);
51811e25f0dSDavid C Somayajulu 
51911e25f0dSDavid C Somayajulu 		if (rval)
52011e25f0dSDavid C Somayajulu 			break;
52111e25f0dSDavid C Somayajulu 
52211e25f0dSDavid C Somayajulu 		regs->reg_buf_len += (dwords << 2);
52311e25f0dSDavid C Somayajulu 
52411e25f0dSDavid C Somayajulu 		rval = copyout(ha->grcdump[i], outb, ha->grcdump_size[i]);
52511e25f0dSDavid C Somayajulu 
52611e25f0dSDavid C Somayajulu 		if (rval)
52711e25f0dSDavid C Somayajulu 			break;
52811e25f0dSDavid C Somayajulu 
52911e25f0dSDavid C Somayajulu 		ha->grcdump_dwords[i] = 0;
53011e25f0dSDavid C Somayajulu 		outb += regs->reg_buf_len;
53111e25f0dSDavid C Somayajulu 	}
53211e25f0dSDavid C Somayajulu 
53311e25f0dSDavid C Somayajulu 	ha->grcdump_taken = 0;
53411e25f0dSDavid C Somayajulu 
53511e25f0dSDavid C Somayajulu 	return (rval);
53611e25f0dSDavid C Somayajulu }
53711e25f0dSDavid C Somayajulu 
538d576ccdfSRyan Libby extern char qlnx_name_str[];
539d576ccdfSRyan Libby extern char qlnx_ver_str[];
540d576ccdfSRyan Libby 
54111e25f0dSDavid C Somayajulu static int
54211e25f0dSDavid C Somayajulu qlnx_drv_info(qlnx_host_t *ha, qlnx_drvinfo_t *drv_info)
54311e25f0dSDavid C Somayajulu {
54411e25f0dSDavid C Somayajulu 	int i;
54511e25f0dSDavid C Somayajulu 
54611e25f0dSDavid C Somayajulu 	bzero(drv_info, sizeof(qlnx_drvinfo_t));
54711e25f0dSDavid C Somayajulu 
54811e25f0dSDavid C Somayajulu 	snprintf(drv_info->drv_name, sizeof(drv_info->drv_name), "%s",
54911e25f0dSDavid C Somayajulu 		qlnx_name_str);
55011e25f0dSDavid C Somayajulu 	snprintf(drv_info->drv_version, sizeof(drv_info->drv_version), "%s",
55111e25f0dSDavid C Somayajulu 		qlnx_ver_str);
55211e25f0dSDavid C Somayajulu 	snprintf(drv_info->mfw_version, sizeof(drv_info->mfw_version), "%s",
55311e25f0dSDavid C Somayajulu 		ha->mfw_ver);
55411e25f0dSDavid C Somayajulu 	snprintf(drv_info->stormfw_version, sizeof(drv_info->stormfw_version),
55511e25f0dSDavid C Somayajulu 		"%s", ha->stormfw_ver);
55611e25f0dSDavid C Somayajulu 
55711e25f0dSDavid C Somayajulu 	drv_info->eeprom_dump_len = ha->flash_size;
55811e25f0dSDavid C Somayajulu 
55911e25f0dSDavid C Somayajulu 	for (i = 0; i < ha->cdev.num_hwfns; i++) {
56011e25f0dSDavid C Somayajulu 		drv_info->reg_dump_len += ha->grcdump_size[i];
56111e25f0dSDavid C Somayajulu 	}
56211e25f0dSDavid C Somayajulu 
56311e25f0dSDavid C Somayajulu 	snprintf(drv_info->bus_info, sizeof(drv_info->bus_info),
56411e25f0dSDavid C Somayajulu 		"%d:%d:%d", pci_get_bus(ha->pci_dev),
56511e25f0dSDavid C Somayajulu 		pci_get_slot(ha->pci_dev), ha->pci_func);
56611e25f0dSDavid C Somayajulu 
56711e25f0dSDavid C Somayajulu 	return (0);
56811e25f0dSDavid C Somayajulu }
56911e25f0dSDavid C Somayajulu 
57011e25f0dSDavid C Somayajulu static int
57111e25f0dSDavid C Somayajulu qlnx_dev_settings(qlnx_host_t *ha, qlnx_dev_setting_t *dev_info)
57211e25f0dSDavid C Somayajulu {
57311e25f0dSDavid C Somayajulu 	struct ecore_hwfn *p_hwfn;
57411e25f0dSDavid C Somayajulu 	struct qlnx_link_output if_link;
57511e25f0dSDavid C Somayajulu 
57611e25f0dSDavid C Somayajulu 	p_hwfn = &ha->cdev.hwfns[0];
57711e25f0dSDavid C Somayajulu 
578*217ec208SDavid C Somayajulu 	qlnx_fill_link(ha, p_hwfn, &if_link);
57911e25f0dSDavid C Somayajulu 
58011e25f0dSDavid C Somayajulu 	dev_info->supported = if_link.supported_caps;
58111e25f0dSDavid C Somayajulu 	dev_info->advertising = if_link.advertised_caps;
58211e25f0dSDavid C Somayajulu 	dev_info->speed = if_link.speed;
58311e25f0dSDavid C Somayajulu 	dev_info->duplex = if_link.duplex;
58411e25f0dSDavid C Somayajulu 	dev_info->port = ha->pci_func & 0x1;
58511e25f0dSDavid C Somayajulu 	dev_info->autoneg = if_link.autoneg;
58611e25f0dSDavid C Somayajulu 
58711e25f0dSDavid C Somayajulu 	return (0);
58811e25f0dSDavid C Somayajulu }
58911e25f0dSDavid C Somayajulu 
59011e25f0dSDavid C Somayajulu static int
59111e25f0dSDavid C Somayajulu qlnx_write_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram, uint32_t cmd)
59211e25f0dSDavid C Somayajulu {
59311e25f0dSDavid C Somayajulu 	uint8_t *buf;
59411e25f0dSDavid C Somayajulu 	int ret = 0;
59511e25f0dSDavid C Somayajulu 
59611e25f0dSDavid C Somayajulu 	if ((nvram->data == NULL) || (nvram->data_len == 0))
59711e25f0dSDavid C Somayajulu 		return (EINVAL);
59811e25f0dSDavid C Somayajulu 
59911e25f0dSDavid C Somayajulu 	buf = qlnx_zalloc(nvram->data_len);
60011e25f0dSDavid C Somayajulu 
60111e25f0dSDavid C Somayajulu 	ret = copyin(nvram->data, buf, nvram->data_len);
60211e25f0dSDavid C Somayajulu 
6037a377fbeSDavid C Somayajulu 	QL_DPRINT9(ha, "issue cmd = 0x%x data = %p \
6047a377fbeSDavid C Somayajulu 		 data_len = 0x%x ret = 0x%x exit\n",
6057a377fbeSDavid C Somayajulu 		cmd, nvram->data, nvram->data_len, ret);
60611e25f0dSDavid C Somayajulu 
60711e25f0dSDavid C Somayajulu 	if (ret == 0) {
60811e25f0dSDavid C Somayajulu 		ret = ecore_mcp_nvm_write(&ha->cdev, cmd,
60911e25f0dSDavid C Somayajulu 			nvram->offset, buf, nvram->data_len);
61011e25f0dSDavid C Somayajulu 	}
61111e25f0dSDavid C Somayajulu 
6127a377fbeSDavid C Somayajulu 	QL_DPRINT9(ha, "cmd = 0x%x data = %p \
6137a377fbeSDavid C Somayajulu 		 data_len = 0x%x resp = 0x%x ret = 0x%x exit\n",
6147a377fbeSDavid C Somayajulu 		cmd, nvram->data, nvram->data_len, ha->cdev.mcp_nvm_resp, ret);
61511e25f0dSDavid C Somayajulu 
61611e25f0dSDavid C Somayajulu 	free(buf, M_QLNXBUF);
61711e25f0dSDavid C Somayajulu 
61811e25f0dSDavid C Somayajulu 	return (ret);
61911e25f0dSDavid C Somayajulu }
62011e25f0dSDavid C Somayajulu 
62111e25f0dSDavid C Somayajulu static int
62211e25f0dSDavid C Somayajulu qlnx_read_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram)
62311e25f0dSDavid C Somayajulu {
62411e25f0dSDavid C Somayajulu 	uint8_t *buf;
62511e25f0dSDavid C Somayajulu 	int ret = 0;
62611e25f0dSDavid C Somayajulu 
62711e25f0dSDavid C Somayajulu 	if ((nvram->data == NULL) || (nvram->data_len == 0))
62811e25f0dSDavid C Somayajulu 		return (EINVAL);
62911e25f0dSDavid C Somayajulu 
63011e25f0dSDavid C Somayajulu 	buf = qlnx_zalloc(nvram->data_len);
63111e25f0dSDavid C Somayajulu 
63211e25f0dSDavid C Somayajulu 	ret = ecore_mcp_nvm_read(&ha->cdev, nvram->offset, buf,
63311e25f0dSDavid C Somayajulu 		nvram->data_len);
63411e25f0dSDavid C Somayajulu 
6357a377fbeSDavid C Somayajulu 	QL_DPRINT9(ha, " data = %p data_len = 0x%x \
6367a377fbeSDavid C Somayajulu 		 resp = 0x%x ret = 0x%x exit\n",
6377a377fbeSDavid C Somayajulu 		nvram->data, nvram->data_len, ha->cdev.mcp_nvm_resp, ret);
63811e25f0dSDavid C Somayajulu 
63911e25f0dSDavid C Somayajulu 	if (ret == 0) {
64011e25f0dSDavid C Somayajulu 		ret = copyout(buf, nvram->data, nvram->data_len);
64111e25f0dSDavid C Somayajulu 	}
64211e25f0dSDavid C Somayajulu 
64311e25f0dSDavid C Somayajulu 	free(buf, M_QLNXBUF);
64411e25f0dSDavid C Somayajulu 
64511e25f0dSDavid C Somayajulu 	return (ret);
64611e25f0dSDavid C Somayajulu }
64711e25f0dSDavid C Somayajulu 
64811e25f0dSDavid C Somayajulu static int
64911e25f0dSDavid C Somayajulu qlnx_get_nvram_resp(qlnx_host_t *ha, qlnx_nvram_t *nvram)
65011e25f0dSDavid C Somayajulu {
65111e25f0dSDavid C Somayajulu 	uint8_t *buf;
65211e25f0dSDavid C Somayajulu 	int ret = 0;
65311e25f0dSDavid C Somayajulu 
65411e25f0dSDavid C Somayajulu 	if ((nvram->data == NULL) || (nvram->data_len == 0))
65511e25f0dSDavid C Somayajulu 		return (EINVAL);
65611e25f0dSDavid C Somayajulu 
65711e25f0dSDavid C Somayajulu 	buf = qlnx_zalloc(nvram->data_len);
65811e25f0dSDavid C Somayajulu 
65911e25f0dSDavid C Somayajulu 
66011e25f0dSDavid C Somayajulu 	ret = ecore_mcp_nvm_resp(&ha->cdev, buf);
66111e25f0dSDavid C Somayajulu 
6627a377fbeSDavid C Somayajulu 	QL_DPRINT9(ha, "data = %p data_len = 0x%x \
6637a377fbeSDavid C Somayajulu 		 resp = 0x%x ret = 0x%x exit\n",
6647a377fbeSDavid C Somayajulu 		nvram->data, nvram->data_len, ha->cdev.mcp_nvm_resp, ret);
66511e25f0dSDavid C Somayajulu 
66611e25f0dSDavid C Somayajulu 	if (ret == 0) {
66711e25f0dSDavid C Somayajulu 		ret = copyout(buf, nvram->data, nvram->data_len);
66811e25f0dSDavid C Somayajulu 	}
66911e25f0dSDavid C Somayajulu 
67011e25f0dSDavid C Somayajulu 	free(buf, M_QLNXBUF);
67111e25f0dSDavid C Somayajulu 
67211e25f0dSDavid C Somayajulu 	return (ret);
67311e25f0dSDavid C Somayajulu }
67411e25f0dSDavid C Somayajulu 
67511e25f0dSDavid C Somayajulu static int
67611e25f0dSDavid C Somayajulu qlnx_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram)
67711e25f0dSDavid C Somayajulu {
67811e25f0dSDavid C Somayajulu 	int ret = 0;
67911e25f0dSDavid C Somayajulu 
68011e25f0dSDavid C Somayajulu 	switch (nvram->cmd) {
68111e25f0dSDavid C Somayajulu 
68211e25f0dSDavid C Somayajulu 	case QLNX_NVRAM_CMD_WRITE_NVRAM:
68311e25f0dSDavid C Somayajulu 		ret = qlnx_write_nvram(ha, nvram, ECORE_NVM_WRITE_NVRAM);
68411e25f0dSDavid C Somayajulu 		break;
68511e25f0dSDavid C Somayajulu 
68611e25f0dSDavid C Somayajulu 	case QLNX_NVRAM_CMD_PUT_FILE_DATA:
68711e25f0dSDavid C Somayajulu 		ret = qlnx_write_nvram(ha, nvram, ECORE_PUT_FILE_DATA);
68811e25f0dSDavid C Somayajulu 		break;
68911e25f0dSDavid C Somayajulu 
69011e25f0dSDavid C Somayajulu 	case QLNX_NVRAM_CMD_READ_NVRAM:
69111e25f0dSDavid C Somayajulu 		ret = qlnx_read_nvram(ha, nvram);
69211e25f0dSDavid C Somayajulu 		break;
69311e25f0dSDavid C Somayajulu 
69411e25f0dSDavid C Somayajulu 	case QLNX_NVRAM_CMD_SET_SECURE_MODE:
69511e25f0dSDavid C Somayajulu 		ret = ecore_mcp_nvm_set_secure_mode(&ha->cdev, nvram->offset);
69611e25f0dSDavid C Somayajulu 
6977a377fbeSDavid C Somayajulu 		QL_DPRINT9(ha, "QLNX_NVRAM_CMD_SET_SECURE_MODE \
6987a377fbeSDavid C Somayajulu 			 resp = 0x%x ret = 0x%x exit\n",
6997a377fbeSDavid C Somayajulu 			 ha->cdev.mcp_nvm_resp, ret);
70011e25f0dSDavid C Somayajulu 		break;
70111e25f0dSDavid C Somayajulu 
70211e25f0dSDavid C Somayajulu 	case QLNX_NVRAM_CMD_DEL_FILE:
70311e25f0dSDavid C Somayajulu 		ret = ecore_mcp_nvm_del_file(&ha->cdev, nvram->offset);
70411e25f0dSDavid C Somayajulu 
7057a377fbeSDavid C Somayajulu 		QL_DPRINT9(ha, "QLNX_NVRAM_CMD_DEL_FILE \
7067a377fbeSDavid C Somayajulu 			 resp = 0x%x ret = 0x%x exit\n",
7077a377fbeSDavid C Somayajulu 			ha->cdev.mcp_nvm_resp, ret);
70811e25f0dSDavid C Somayajulu 		break;
70911e25f0dSDavid C Somayajulu 
71011e25f0dSDavid C Somayajulu 	case QLNX_NVRAM_CMD_PUT_FILE_BEGIN:
71111e25f0dSDavid C Somayajulu 		ret = ecore_mcp_nvm_put_file_begin(&ha->cdev, nvram->offset);
71211e25f0dSDavid C Somayajulu 
7137a377fbeSDavid C Somayajulu 		QL_DPRINT9(ha, "QLNX_NVRAM_CMD_PUT_FILE_BEGIN \
7147a377fbeSDavid C Somayajulu 			 resp = 0x%x ret = 0x%x exit\n",
7157a377fbeSDavid C Somayajulu 			ha->cdev.mcp_nvm_resp, ret);
71611e25f0dSDavid C Somayajulu 		break;
71711e25f0dSDavid C Somayajulu 
71811e25f0dSDavid C Somayajulu 	case QLNX_NVRAM_CMD_GET_NVRAM_RESP:
71911e25f0dSDavid C Somayajulu 		ret = qlnx_get_nvram_resp(ha, nvram);
72011e25f0dSDavid C Somayajulu 		break;
72111e25f0dSDavid C Somayajulu 
72211e25f0dSDavid C Somayajulu 	default:
72311e25f0dSDavid C Somayajulu 		ret = EINVAL;
72411e25f0dSDavid C Somayajulu 		break;
72511e25f0dSDavid C Somayajulu 	}
72611e25f0dSDavid C Somayajulu 
72711e25f0dSDavid C Somayajulu 	return (ret);
72811e25f0dSDavid C Somayajulu }
72911e25f0dSDavid C Somayajulu 
73011e25f0dSDavid C Somayajulu static void
73111e25f0dSDavid C Somayajulu qlnx_storm_stats(qlnx_host_t *ha, qlnx_storm_stats_dump_t *s_stats)
73211e25f0dSDavid C Somayajulu {
73311e25f0dSDavid C Somayajulu 	int i;
73411e25f0dSDavid C Somayajulu 	int index;
73511e25f0dSDavid C Somayajulu 	int ret;
73611e25f0dSDavid C Somayajulu 	int stats_copied = 0;
73711e25f0dSDavid C Somayajulu 
73811e25f0dSDavid C Somayajulu 	s_stats->num_hwfns = ha->cdev.num_hwfns;
73911e25f0dSDavid C Somayajulu 
74011e25f0dSDavid C Somayajulu //	if (ha->storm_stats_index < QLNX_STORM_STATS_SAMPLES_PER_HWFN)
74111e25f0dSDavid C Somayajulu //		return;
74211e25f0dSDavid C Somayajulu 
74311e25f0dSDavid C Somayajulu 	s_stats->num_samples = ha->storm_stats_index;
74411e25f0dSDavid C Somayajulu 
74511e25f0dSDavid C Somayajulu 	for (i = 0; i < ha->cdev.num_hwfns; i++) {
74611e25f0dSDavid C Somayajulu 
74711e25f0dSDavid C Somayajulu 		index = (QLNX_STORM_STATS_SAMPLES_PER_HWFN * i);
74811e25f0dSDavid C Somayajulu 
74911e25f0dSDavid C Somayajulu 		if (s_stats->buffer[i]) {
75011e25f0dSDavid C Somayajulu 
75111e25f0dSDavid C Somayajulu 			ret = copyout(&ha->storm_stats[index],
75211e25f0dSDavid C Somayajulu 					s_stats->buffer[i],
75311e25f0dSDavid C Somayajulu 					QLNX_STORM_STATS_BYTES_PER_HWFN);
75411e25f0dSDavid C Somayajulu 			if (ret) {
75511e25f0dSDavid C Somayajulu 				printf("%s [%d]: failed\n", __func__, i);
75611e25f0dSDavid C Somayajulu 			}
75711e25f0dSDavid C Somayajulu 
75811e25f0dSDavid C Somayajulu 			if (s_stats->num_samples ==
75911e25f0dSDavid C Somayajulu 				QLNX_STORM_STATS_SAMPLES_PER_HWFN) {
76011e25f0dSDavid C Somayajulu 
76111e25f0dSDavid C Somayajulu 				bzero((void *)&ha->storm_stats[i],
76211e25f0dSDavid C Somayajulu 					QLNX_STORM_STATS_BYTES_PER_HWFN);
76311e25f0dSDavid C Somayajulu 
76411e25f0dSDavid C Somayajulu 				stats_copied = 1;
76511e25f0dSDavid C Somayajulu 			}
76611e25f0dSDavid C Somayajulu 		}
76711e25f0dSDavid C Somayajulu 	}
76811e25f0dSDavid C Somayajulu 
76911e25f0dSDavid C Somayajulu 	if (stats_copied)
77011e25f0dSDavid C Somayajulu 		ha->storm_stats_index = 0;
77111e25f0dSDavid C Somayajulu 
77211e25f0dSDavid C Somayajulu 	return;
77311e25f0dSDavid C Somayajulu }
77411e25f0dSDavid C Somayajulu 
775*217ec208SDavid C Somayajulu #ifdef QLNX_USER_LLDP
776*217ec208SDavid C Somayajulu 
777*217ec208SDavid C Somayajulu static int
778*217ec208SDavid C Somayajulu qlnx_lldp_configure(qlnx_host_t *ha, struct ecore_hwfn *p_hwfn,
779*217ec208SDavid C Somayajulu 	struct ecore_ptt *p_ptt, uint32_t enable)
780*217ec208SDavid C Somayajulu {
781*217ec208SDavid C Somayajulu 	int ret = 0;
782*217ec208SDavid C Somayajulu 	uint8_t lldp_mac[6] = {0};
783*217ec208SDavid C Somayajulu 	struct ecore_lldp_config_params lldp_params;
784*217ec208SDavid C Somayajulu 	struct ecore_lldp_sys_tlvs tlv_params;
785*217ec208SDavid C Somayajulu 
786*217ec208SDavid C Somayajulu 	ret = ecore_mcp_get_lldp_mac(p_hwfn, p_ptt, lldp_mac);
787*217ec208SDavid C Somayajulu 
788*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
789*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
790*217ec208SDavid C Somayajulu 			"%s: ecore_mcp_get_lldp_mac failed\n", __func__);
791*217ec208SDavid C Somayajulu                 return (-1);
792*217ec208SDavid C Somayajulu 	}
793*217ec208SDavid C Somayajulu 
794*217ec208SDavid C Somayajulu 	bzero(&lldp_params, sizeof(struct ecore_lldp_config_params));
795*217ec208SDavid C Somayajulu 	bzero(&tlv_params, sizeof(struct ecore_lldp_sys_tlvs));
796*217ec208SDavid C Somayajulu 
797*217ec208SDavid C Somayajulu 	lldp_params.agent = ECORE_LLDP_NEAREST_BRIDGE;
798*217ec208SDavid C Somayajulu 	lldp_params.tx_interval = 30; //Default value used as suggested by MFW
799*217ec208SDavid C Somayajulu 	lldp_params.tx_hold = 4; //Default value used as suggested by MFW
800*217ec208SDavid C Somayajulu 	lldp_params.tx_credit = 5; //Default value used as suggested by MFW
801*217ec208SDavid C Somayajulu 	lldp_params.rx_enable = enable ? 1 : 0;
802*217ec208SDavid C Somayajulu 	lldp_params.tx_enable = enable ? 1 : 0;
803*217ec208SDavid C Somayajulu 
804*217ec208SDavid C Somayajulu 	lldp_params.chassis_id_tlv[0] = 0;
805*217ec208SDavid C Somayajulu 	lldp_params.chassis_id_tlv[0] |= (QLNX_LLDP_TYPE_CHASSIS_ID << 1);
806*217ec208SDavid C Somayajulu 	lldp_params.chassis_id_tlv[0] |=
807*217ec208SDavid C Somayajulu 		((QLNX_LLDP_CHASSIS_ID_SUBTYPE_OCTETS +
808*217ec208SDavid C Somayajulu 			QLNX_LLDP_CHASSIS_ID_MAC_ADDR_LEN) << 8);
809*217ec208SDavid C Somayajulu 	lldp_params.chassis_id_tlv[0] |= (QLNX_LLDP_CHASSIS_ID_SUBTYPE_MAC << 16);
810*217ec208SDavid C Somayajulu 	lldp_params.chassis_id_tlv[0] |= lldp_mac[0] << 24;
811*217ec208SDavid C Somayajulu 	lldp_params.chassis_id_tlv[1] = lldp_mac[1] | (lldp_mac[2] << 8) |
812*217ec208SDavid C Somayajulu 		 (lldp_mac[3] << 16) | (lldp_mac[4] << 24);
813*217ec208SDavid C Somayajulu 	lldp_params.chassis_id_tlv[2] = lldp_mac[5];
814*217ec208SDavid C Somayajulu 
815*217ec208SDavid C Somayajulu 
816*217ec208SDavid C Somayajulu 	lldp_params.port_id_tlv[0] = 0;
817*217ec208SDavid C Somayajulu 	lldp_params.port_id_tlv[0] |= (QLNX_LLDP_TYPE_PORT_ID << 1);
818*217ec208SDavid C Somayajulu 	lldp_params.port_id_tlv[0] |=
819*217ec208SDavid C Somayajulu 		((QLNX_LLDP_PORT_ID_SUBTYPE_OCTETS +
820*217ec208SDavid C Somayajulu 			QLNX_LLDP_PORT_ID_MAC_ADDR_LEN) << 8);
821*217ec208SDavid C Somayajulu 	lldp_params.port_id_tlv[0] |= (QLNX_LLDP_PORT_ID_SUBTYPE_MAC << 16);
822*217ec208SDavid C Somayajulu 	lldp_params.port_id_tlv[0] |= lldp_mac[0] << 24;
823*217ec208SDavid C Somayajulu 	lldp_params.port_id_tlv[1] = lldp_mac[1] | (lldp_mac[2] << 8) |
824*217ec208SDavid C Somayajulu 		 (lldp_mac[3] << 16) | (lldp_mac[4] << 24);
825*217ec208SDavid C Somayajulu 	lldp_params.port_id_tlv[2] = lldp_mac[5];
826*217ec208SDavid C Somayajulu 
827*217ec208SDavid C Somayajulu 	ret = ecore_lldp_set_params(p_hwfn, p_ptt, &lldp_params);
828*217ec208SDavid C Somayajulu 
829*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
830*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
831*217ec208SDavid C Somayajulu 			"%s: ecore_lldp_set_params failed\n", __func__);
832*217ec208SDavid C Somayajulu                 return (-1);
833*217ec208SDavid C Somayajulu 	}
834*217ec208SDavid C Somayajulu 
835*217ec208SDavid C Somayajulu 	//If LLDP is disable then disable discard_mandatory_tlv flag
836*217ec208SDavid C Somayajulu 	if (!enable) {
837*217ec208SDavid C Somayajulu 		tlv_params.discard_mandatory_tlv = false;
838*217ec208SDavid C Somayajulu 		tlv_params.buf_size = 0;
839*217ec208SDavid C Somayajulu 		ret = ecore_lldp_set_system_tlvs(p_hwfn, p_ptt, &tlv_params);
840*217ec208SDavid C Somayajulu     	}
841*217ec208SDavid C Somayajulu 
842*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
843*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
844*217ec208SDavid C Somayajulu 			"%s: ecore_lldp_set_system_tlvs failed\n", __func__);
845*217ec208SDavid C Somayajulu 	}
846*217ec208SDavid C Somayajulu 
847*217ec208SDavid C Somayajulu 	return (ret);
848*217ec208SDavid C Somayajulu }
849*217ec208SDavid C Somayajulu 
850*217ec208SDavid C Somayajulu static int
851*217ec208SDavid C Somayajulu qlnx_register_default_lldp_tlvs(qlnx_host_t *ha, struct ecore_hwfn *p_hwfn,
852*217ec208SDavid C Somayajulu 	struct ecore_ptt *p_ptt)
853*217ec208SDavid C Somayajulu {
854*217ec208SDavid C Somayajulu 	int ret = 0;
855*217ec208SDavid C Somayajulu 
856*217ec208SDavid C Somayajulu 	ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
857*217ec208SDavid C Somayajulu 			ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_CHASSIS_ID);
858*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
859*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
860*217ec208SDavid C Somayajulu 			"%s: QLNX_LLDP_TYPE_CHASSIS_ID failed\n", __func__);
861*217ec208SDavid C Somayajulu 		goto qlnx_register_default_lldp_tlvs_exit;
862*217ec208SDavid C Somayajulu 	}
863*217ec208SDavid C Somayajulu 
864*217ec208SDavid C Somayajulu 	//register Port ID TLV
865*217ec208SDavid C Somayajulu 	ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
866*217ec208SDavid C Somayajulu 			ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_PORT_ID);
867*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
868*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
869*217ec208SDavid C Somayajulu 			"%s: QLNX_LLDP_TYPE_PORT_ID failed\n", __func__);
870*217ec208SDavid C Somayajulu 		goto qlnx_register_default_lldp_tlvs_exit;
871*217ec208SDavid C Somayajulu 	}
872*217ec208SDavid C Somayajulu 
873*217ec208SDavid C Somayajulu 	//register TTL TLV
874*217ec208SDavid C Somayajulu 	ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
875*217ec208SDavid C Somayajulu 			ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_TTL);
876*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
877*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
878*217ec208SDavid C Somayajulu 			"%s: QLNX_LLDP_TYPE_TTL failed\n", __func__);
879*217ec208SDavid C Somayajulu 		goto qlnx_register_default_lldp_tlvs_exit;
880*217ec208SDavid C Somayajulu 	}
881*217ec208SDavid C Somayajulu 
882*217ec208SDavid C Somayajulu 	//register Port Description TLV
883*217ec208SDavid C Somayajulu 	ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
884*217ec208SDavid C Somayajulu 			ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_PORT_DESC);
885*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
886*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
887*217ec208SDavid C Somayajulu 			"%s: QLNX_LLDP_TYPE_PORT_DESC failed\n", __func__);
888*217ec208SDavid C Somayajulu 		goto qlnx_register_default_lldp_tlvs_exit;
889*217ec208SDavid C Somayajulu 	}
890*217ec208SDavid C Somayajulu 
891*217ec208SDavid C Somayajulu 	//register System Name TLV
892*217ec208SDavid C Somayajulu 	ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
893*217ec208SDavid C Somayajulu 			ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_SYS_NAME);
894*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
895*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
896*217ec208SDavid C Somayajulu 			"%s: QLNX_LLDP_TYPE_SYS_NAME failed\n", __func__);
897*217ec208SDavid C Somayajulu 		goto qlnx_register_default_lldp_tlvs_exit;
898*217ec208SDavid C Somayajulu 	}
899*217ec208SDavid C Somayajulu 
900*217ec208SDavid C Somayajulu 	//register System Description TLV
901*217ec208SDavid C Somayajulu 	ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
902*217ec208SDavid C Somayajulu 			ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_SYS_DESC);
903*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
904*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
905*217ec208SDavid C Somayajulu 			"%s: QLNX_LLDP_TYPE_SYS_DESC failed\n", __func__);
906*217ec208SDavid C Somayajulu 		goto qlnx_register_default_lldp_tlvs_exit;
907*217ec208SDavid C Somayajulu 	}
908*217ec208SDavid C Somayajulu 
909*217ec208SDavid C Somayajulu 	//register System Capabilities TLV
910*217ec208SDavid C Somayajulu 	ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
911*217ec208SDavid C Somayajulu 			ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_SYS_CAPS);
912*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
913*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
914*217ec208SDavid C Somayajulu 			"%s: QLNX_LLDP_TYPE_SYS_CAPS failed\n", __func__);
915*217ec208SDavid C Somayajulu 		goto qlnx_register_default_lldp_tlvs_exit;
916*217ec208SDavid C Somayajulu 	}
917*217ec208SDavid C Somayajulu 
918*217ec208SDavid C Somayajulu 	//register Management Address TLV
919*217ec208SDavid C Somayajulu 	ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
920*217ec208SDavid C Somayajulu 			ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_MGMT_ADDR);
921*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
922*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
923*217ec208SDavid C Somayajulu 			"%s: QLNX_LLDP_TYPE_MGMT_ADDR failed\n", __func__);
924*217ec208SDavid C Somayajulu 		goto qlnx_register_default_lldp_tlvs_exit;
925*217ec208SDavid C Somayajulu 	}
926*217ec208SDavid C Somayajulu 
927*217ec208SDavid C Somayajulu 	//register Organizationally Specific TLVs
928*217ec208SDavid C Somayajulu 	ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
929*217ec208SDavid C Somayajulu 			ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_ORG_SPECIFIC);
930*217ec208SDavid C Somayajulu 	if (ret != ECORE_SUCCESS) {
931*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
932*217ec208SDavid C Somayajulu 			"%s: QLNX_LLDP_TYPE_ORG_SPECIFIC failed\n", __func__);
933*217ec208SDavid C Somayajulu 	}
934*217ec208SDavid C Somayajulu 
935*217ec208SDavid C Somayajulu qlnx_register_default_lldp_tlvs_exit:
936*217ec208SDavid C Somayajulu 	return (ret);
937*217ec208SDavid C Somayajulu }
938*217ec208SDavid C Somayajulu 
939*217ec208SDavid C Somayajulu int
940*217ec208SDavid C Somayajulu qlnx_set_lldp_tlvx(qlnx_host_t *ha, qlnx_lldp_sys_tlvs_t *lldp_tlvs)
941*217ec208SDavid C Somayajulu {
942*217ec208SDavid C Somayajulu 	int ret = 0;
943*217ec208SDavid C Somayajulu 	struct ecore_hwfn *p_hwfn;
944*217ec208SDavid C Somayajulu 	struct ecore_ptt *p_ptt;
945*217ec208SDavid C Somayajulu 	struct ecore_lldp_sys_tlvs tlv_params;
946*217ec208SDavid C Somayajulu 
947*217ec208SDavid C Somayajulu 	p_hwfn = &ha->cdev.hwfns[0];
948*217ec208SDavid C Somayajulu 	p_ptt = ecore_ptt_acquire(p_hwfn);
949*217ec208SDavid C Somayajulu 
950*217ec208SDavid C Somayajulu         if (!p_ptt) {
951*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
952*217ec208SDavid C Somayajulu 			"%s: ecore_ptt_acquire failed\n", __func__);
953*217ec208SDavid C Somayajulu                 return (ENXIO);
954*217ec208SDavid C Somayajulu         }
955*217ec208SDavid C Somayajulu 
956*217ec208SDavid C Somayajulu 	ret = qlnx_lldp_configure(ha, p_hwfn, p_ptt, 0);
957*217ec208SDavid C Somayajulu 
958*217ec208SDavid C Somayajulu 	if (ret) {
959*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
960*217ec208SDavid C Somayajulu 			"%s: qlnx_lldp_configure disable failed\n", __func__);
961*217ec208SDavid C Somayajulu 		goto qlnx_set_lldp_tlvx_exit;
962*217ec208SDavid C Somayajulu 	}
963*217ec208SDavid C Somayajulu 
964*217ec208SDavid C Somayajulu 	ret = qlnx_register_default_lldp_tlvs(ha, p_hwfn, p_ptt);
965*217ec208SDavid C Somayajulu 
966*217ec208SDavid C Somayajulu 	if (ret) {
967*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
968*217ec208SDavid C Somayajulu 			"%s: qlnx_register_default_lldp_tlvs failed\n",
969*217ec208SDavid C Somayajulu 			__func__);
970*217ec208SDavid C Somayajulu 		goto qlnx_set_lldp_tlvx_exit;
971*217ec208SDavid C Somayajulu 	}
972*217ec208SDavid C Somayajulu 
973*217ec208SDavid C Somayajulu 	ret = qlnx_lldp_configure(ha, p_hwfn, p_ptt, 1);
974*217ec208SDavid C Somayajulu 
975*217ec208SDavid C Somayajulu 	if (ret) {
976*217ec208SDavid C Somayajulu                 device_printf(ha->pci_dev,
977*217ec208SDavid C Somayajulu 			"%s: qlnx_lldp_configure enable failed\n", __func__);
978*217ec208SDavid C Somayajulu 		goto qlnx_set_lldp_tlvx_exit;
979*217ec208SDavid C Somayajulu 	}
980*217ec208SDavid C Somayajulu 
981*217ec208SDavid C Somayajulu 	if (lldp_tlvs != NULL) {
982*217ec208SDavid C Somayajulu 		bzero(&tlv_params, sizeof(struct ecore_lldp_sys_tlvs));
983*217ec208SDavid C Somayajulu 
984*217ec208SDavid C Somayajulu 		tlv_params.discard_mandatory_tlv =
985*217ec208SDavid C Somayajulu 			(lldp_tlvs->discard_mandatory_tlv ? true: false);
986*217ec208SDavid C Somayajulu 		tlv_params.buf_size = lldp_tlvs->buf_size;
987*217ec208SDavid C Somayajulu 		memcpy(tlv_params.buf, lldp_tlvs->buf, lldp_tlvs->buf_size);
988*217ec208SDavid C Somayajulu 
989*217ec208SDavid C Somayajulu 		ret = ecore_lldp_set_system_tlvs(p_hwfn, p_ptt, &tlv_params);
990*217ec208SDavid C Somayajulu 
991*217ec208SDavid C Somayajulu 		if (ret) {
992*217ec208SDavid C Somayajulu 			device_printf(ha->pci_dev,
993*217ec208SDavid C Somayajulu 				"%s: ecore_lldp_set_system_tlvs failed\n",
994*217ec208SDavid C Somayajulu 				__func__);
995*217ec208SDavid C Somayajulu 		}
996*217ec208SDavid C Somayajulu 	}
997*217ec208SDavid C Somayajulu qlnx_set_lldp_tlvx_exit:
998*217ec208SDavid C Somayajulu 
999*217ec208SDavid C Somayajulu 	ecore_ptt_release(p_hwfn, p_ptt);
1000*217ec208SDavid C Somayajulu 	return (ret);
1001*217ec208SDavid C Somayajulu }
1002*217ec208SDavid C Somayajulu 
1003*217ec208SDavid C Somayajulu #endif /* #ifdef QLNX_USER_LLDP */
100411e25f0dSDavid C Somayajulu 
100511e25f0dSDavid C Somayajulu static int
100611e25f0dSDavid C Somayajulu qlnx_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
100711e25f0dSDavid C Somayajulu 	struct thread *td)
100811e25f0dSDavid C Somayajulu {
100911e25f0dSDavid C Somayajulu 	qlnx_host_t	*ha;
101011e25f0dSDavid C Somayajulu 	int		rval = 0;
101111e25f0dSDavid C Somayajulu 	struct ifnet	*ifp;
101211e25f0dSDavid C Somayajulu 	qlnx_trace_t	*trace;
101311e25f0dSDavid C Somayajulu 	int		i;
101411e25f0dSDavid C Somayajulu 
101511e25f0dSDavid C Somayajulu 	if ((ha = (qlnx_host_t *)dev->si_drv1) == NULL)
101611e25f0dSDavid C Somayajulu 		return ENXIO;
101711e25f0dSDavid C Somayajulu 
101811e25f0dSDavid C Somayajulu 	ifp = ha->ifp;
101911e25f0dSDavid C Somayajulu 
102011e25f0dSDavid C Somayajulu 	switch (cmd) {
102111e25f0dSDavid C Somayajulu 
102211e25f0dSDavid C Somayajulu 	case QLNX_GRC_DUMP_SIZE:
102311e25f0dSDavid C Somayajulu 		qlnx_get_grc_dump_size(ha, (qlnx_grcdump_t *)data);
102411e25f0dSDavid C Somayajulu 		break;
102511e25f0dSDavid C Somayajulu 
102611e25f0dSDavid C Somayajulu 	case QLNX_GRC_DUMP:
102711e25f0dSDavid C Somayajulu 		rval = qlnx_get_grc_dump(ha, (qlnx_grcdump_t *)data);
102811e25f0dSDavid C Somayajulu 		break;
102911e25f0dSDavid C Somayajulu 
103011e25f0dSDavid C Somayajulu 	case QLNX_IDLE_CHK_SIZE:
103111e25f0dSDavid C Somayajulu 		qlnx_get_idle_chk_size(ha, (qlnx_idle_chk_t *)data);
103211e25f0dSDavid C Somayajulu 		break;
103311e25f0dSDavid C Somayajulu 
103411e25f0dSDavid C Somayajulu 	case QLNX_IDLE_CHK:
103511e25f0dSDavid C Somayajulu 		rval = qlnx_get_idle_chk(ha, (qlnx_idle_chk_t *)data);
103611e25f0dSDavid C Somayajulu 		break;
103711e25f0dSDavid C Somayajulu 
103811e25f0dSDavid C Somayajulu 	case QLNX_DRV_INFO:
103911e25f0dSDavid C Somayajulu 		rval = qlnx_drv_info(ha, (qlnx_drvinfo_t *)data);
104011e25f0dSDavid C Somayajulu 		break;
104111e25f0dSDavid C Somayajulu 
104211e25f0dSDavid C Somayajulu 	case QLNX_DEV_SETTING:
104311e25f0dSDavid C Somayajulu 		rval = qlnx_dev_settings(ha, (qlnx_dev_setting_t *)data);
104411e25f0dSDavid C Somayajulu 		break;
104511e25f0dSDavid C Somayajulu 
104611e25f0dSDavid C Somayajulu 	case QLNX_GET_REGS:
104711e25f0dSDavid C Somayajulu 		rval = qlnx_get_regs(ha, (qlnx_get_regs_t *)data);
104811e25f0dSDavid C Somayajulu 		break;
104911e25f0dSDavid C Somayajulu 
105011e25f0dSDavid C Somayajulu 	case QLNX_NVRAM:
105111e25f0dSDavid C Somayajulu 		rval = qlnx_nvram(ha, (qlnx_nvram_t *)data);
105211e25f0dSDavid C Somayajulu 		break;
105311e25f0dSDavid C Somayajulu 
105411e25f0dSDavid C Somayajulu 	case QLNX_RD_WR_REG:
105511e25f0dSDavid C Somayajulu 		rval = qlnx_reg_rd_wr(ha, (qlnx_reg_rd_wr_t *)data);
105611e25f0dSDavid C Somayajulu 		break;
105711e25f0dSDavid C Somayajulu 
105811e25f0dSDavid C Somayajulu 	case QLNX_RD_WR_PCICFG:
105911e25f0dSDavid C Somayajulu 		rval = qlnx_rd_wr_pci_config(ha, (qlnx_pcicfg_rd_wr_t *)data);
106011e25f0dSDavid C Somayajulu 		break;
106111e25f0dSDavid C Somayajulu 
106211e25f0dSDavid C Somayajulu 	case QLNX_MAC_ADDR:
106311e25f0dSDavid C Somayajulu 		qlnx_mac_addr(ha, (qlnx_perm_mac_addr_t *)data);
106411e25f0dSDavid C Somayajulu 		break;
106511e25f0dSDavid C Somayajulu 
106611e25f0dSDavid C Somayajulu 	case QLNX_STORM_STATS:
106711e25f0dSDavid C Somayajulu 		qlnx_storm_stats(ha, (qlnx_storm_stats_dump_t *)data);
106811e25f0dSDavid C Somayajulu 		break;
106911e25f0dSDavid C Somayajulu 
107011e25f0dSDavid C Somayajulu 	case QLNX_TRACE_SIZE:
107111e25f0dSDavid C Somayajulu 		qlnx_get_trace_size(ha, (qlnx_trace_t *)data);
107211e25f0dSDavid C Somayajulu 		break;
107311e25f0dSDavid C Somayajulu 
107411e25f0dSDavid C Somayajulu 	case QLNX_TRACE:
107511e25f0dSDavid C Somayajulu 		trace = (qlnx_trace_t *)data;
107611e25f0dSDavid C Somayajulu 
107711e25f0dSDavid C Somayajulu 		for (i = 0; i < ha->cdev.num_hwfns; i++) {
107811e25f0dSDavid C Somayajulu 
107911e25f0dSDavid C Somayajulu 			if (trace->size[i] && trace->cmd && trace->buffer[i])
108011e25f0dSDavid C Somayajulu 				rval = qlnx_get_trace(ha, i, trace);
108111e25f0dSDavid C Somayajulu 
108211e25f0dSDavid C Somayajulu 			if (rval)
108311e25f0dSDavid C Somayajulu 				break;
108411e25f0dSDavid C Somayajulu 		}
108511e25f0dSDavid C Somayajulu 		break;
108611e25f0dSDavid C Somayajulu 
1087*217ec208SDavid C Somayajulu #ifdef QLNX_USER_LLDP
1088*217ec208SDavid C Somayajulu 	case QLNX_SET_LLDP_TLVS:
1089*217ec208SDavid C Somayajulu 		rval = qlnx_set_lldp_tlvx(ha, (qlnx_lldp_sys_tlvs_t *)data);
1090*217ec208SDavid C Somayajulu 		break;
1091*217ec208SDavid C Somayajulu #endif /* #ifdef QLNX_USER_LLDP */
1092*217ec208SDavid C Somayajulu 
109311e25f0dSDavid C Somayajulu 	default:
109411e25f0dSDavid C Somayajulu 		rval = EINVAL;
109511e25f0dSDavid C Somayajulu 		break;
109611e25f0dSDavid C Somayajulu 	}
109711e25f0dSDavid C Somayajulu 
109811e25f0dSDavid C Somayajulu 	return (rval);
109911e25f0dSDavid C Somayajulu }
110011e25f0dSDavid C Somayajulu 
1101