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 * File: qlnx_ioctl.c
3011e25f0dSDavid C Somayajulu * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
3111e25f0dSDavid C Somayajulu */
3211e25f0dSDavid C Somayajulu
3311e25f0dSDavid C Somayajulu #include <sys/cdefs.h>
3411e25f0dSDavid C Somayajulu #include "qlnx_os.h"
3511e25f0dSDavid C Somayajulu #include "bcm_osal.h"
3611e25f0dSDavid C Somayajulu
3711e25f0dSDavid C Somayajulu #include "reg_addr.h"
3811e25f0dSDavid C Somayajulu #include "ecore_gtt_reg_addr.h"
3911e25f0dSDavid C Somayajulu #include "ecore.h"
4011e25f0dSDavid C Somayajulu #include "ecore_chain.h"
4111e25f0dSDavid C Somayajulu #include "ecore_status.h"
4211e25f0dSDavid C Somayajulu #include "ecore_hw.h"
4311e25f0dSDavid C Somayajulu #include "ecore_rt_defs.h"
4411e25f0dSDavid C Somayajulu #include "ecore_init_ops.h"
4511e25f0dSDavid C Somayajulu #include "ecore_int.h"
4611e25f0dSDavid C Somayajulu #include "ecore_cxt.h"
4711e25f0dSDavid C Somayajulu #include "ecore_spq.h"
4811e25f0dSDavid C Somayajulu #include "ecore_init_fw_funcs.h"
4911e25f0dSDavid C Somayajulu #include "ecore_sp_commands.h"
5011e25f0dSDavid C Somayajulu #include "ecore_dev_api.h"
5111e25f0dSDavid C Somayajulu #include "ecore_l2_api.h"
5211e25f0dSDavid C Somayajulu #include "ecore_mcp.h"
5311e25f0dSDavid C Somayajulu #include "ecore_hw_defs.h"
5411e25f0dSDavid C Somayajulu #include "mcp_public.h"
5511e25f0dSDavid C Somayajulu #include "ecore_iro.h"
5611e25f0dSDavid C Somayajulu #include "nvm_cfg.h"
5711e25f0dSDavid C Somayajulu #include "ecore_dev_api.h"
5811e25f0dSDavid C Somayajulu #include "ecore_dbg_fw_funcs.h"
59217ec208SDavid C Somayajulu #include "ecore_dcbx_api.h"
6011e25f0dSDavid C Somayajulu
6111e25f0dSDavid C Somayajulu #include "qlnx_ioctl.h"
6211e25f0dSDavid C Somayajulu #include "qlnx_def.h"
6311e25f0dSDavid C Somayajulu #include "qlnx_ver.h"
6411e25f0dSDavid C Somayajulu #include <sys/smp.h>
6511e25f0dSDavid C Somayajulu
6611e25f0dSDavid C Somayajulu static int qlnx_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
6711e25f0dSDavid C Somayajulu struct thread *td);
6811e25f0dSDavid C Somayajulu
6911e25f0dSDavid C Somayajulu static struct cdevsw qlnx_cdevsw = {
7011e25f0dSDavid C Somayajulu .d_version = D_VERSION,
7111e25f0dSDavid C Somayajulu .d_ioctl = qlnx_eioctl,
7211e25f0dSDavid C Somayajulu .d_name = "qlnxioctl",
7311e25f0dSDavid C Somayajulu };
7411e25f0dSDavid C Somayajulu
7511e25f0dSDavid C Somayajulu int
qlnx_make_cdev(qlnx_host_t * ha)7611e25f0dSDavid C Somayajulu qlnx_make_cdev(qlnx_host_t *ha)
7711e25f0dSDavid C Somayajulu {
7811e25f0dSDavid C Somayajulu ha->ioctl_dev = make_dev(&qlnx_cdevsw,
79*727bfe38SJustin Hibbits if_getdunit(ha->ifp),
8011e25f0dSDavid C Somayajulu UID_ROOT,
8111e25f0dSDavid C Somayajulu GID_WHEEL,
8211e25f0dSDavid C Somayajulu 0600,
8311e25f0dSDavid C Somayajulu "%s",
8411e25f0dSDavid C Somayajulu if_name(ha->ifp));
8511e25f0dSDavid C Somayajulu
8611e25f0dSDavid C Somayajulu if (ha->ioctl_dev == NULL)
8711e25f0dSDavid C Somayajulu return (-1);
8811e25f0dSDavid C Somayajulu
8911e25f0dSDavid C Somayajulu ha->ioctl_dev->si_drv1 = ha;
9011e25f0dSDavid C Somayajulu
9111e25f0dSDavid C Somayajulu return (0);
9211e25f0dSDavid C Somayajulu }
9311e25f0dSDavid C Somayajulu
9411e25f0dSDavid C Somayajulu void
qlnx_del_cdev(qlnx_host_t * ha)9511e25f0dSDavid C Somayajulu qlnx_del_cdev(qlnx_host_t *ha)
9611e25f0dSDavid C Somayajulu {
9711e25f0dSDavid C Somayajulu if (ha->ioctl_dev != NULL)
9811e25f0dSDavid C Somayajulu destroy_dev(ha->ioctl_dev);
9911e25f0dSDavid C Somayajulu return;
10011e25f0dSDavid C Somayajulu }
10111e25f0dSDavid C Somayajulu
10211e25f0dSDavid C Somayajulu int
qlnx_grc_dump(qlnx_host_t * ha,uint32_t * num_dumped_dwords,int hwfn_index)10311e25f0dSDavid C Somayajulu qlnx_grc_dump(qlnx_host_t *ha, uint32_t *num_dumped_dwords, int hwfn_index)
10411e25f0dSDavid C Somayajulu {
10511e25f0dSDavid C Somayajulu int rval = EINVAL;
10611e25f0dSDavid C Somayajulu struct ecore_hwfn *p_hwfn;
10711e25f0dSDavid C Somayajulu struct ecore_ptt *p_ptt;
10811e25f0dSDavid C Somayajulu
10911e25f0dSDavid C Somayajulu if (ha->grcdump_dwords[hwfn_index]) {
11011e25f0dSDavid C Somayajulu /* the grcdump is already available */
11111e25f0dSDavid C Somayajulu *num_dumped_dwords = ha->grcdump_dwords[hwfn_index];
11211e25f0dSDavid C Somayajulu return (0);
11311e25f0dSDavid C Somayajulu }
11411e25f0dSDavid C Somayajulu
11511e25f0dSDavid C Somayajulu ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver());
11611e25f0dSDavid C Somayajulu
11711e25f0dSDavid C Somayajulu p_hwfn = &ha->cdev.hwfns[hwfn_index];
11811e25f0dSDavid C Somayajulu p_ptt = ecore_ptt_acquire(p_hwfn);
11911e25f0dSDavid C Somayajulu
12011e25f0dSDavid C Somayajulu if (!p_ptt) {
1217a377fbeSDavid C Somayajulu QL_DPRINT1(ha,"ecore_ptt_acquire failed\n");
12211e25f0dSDavid C Somayajulu return (rval);
12311e25f0dSDavid C Somayajulu }
12411e25f0dSDavid C Somayajulu
12511e25f0dSDavid C Somayajulu if ((rval = ecore_dbg_grc_dump(p_hwfn, p_ptt,
12611e25f0dSDavid C Somayajulu ha->grcdump[hwfn_index],
12711e25f0dSDavid C Somayajulu (ha->grcdump_size[hwfn_index] >> 2),
12811e25f0dSDavid C Somayajulu num_dumped_dwords)) == DBG_STATUS_OK) {
12911e25f0dSDavid C Somayajulu rval = 0;
13011e25f0dSDavid C Somayajulu ha->grcdump_taken = 1;
13111e25f0dSDavid C Somayajulu } else
1327a377fbeSDavid C Somayajulu QL_DPRINT1(ha,"ecore_dbg_grc_dump failed [%d, 0x%x]\n",
1337a377fbeSDavid C Somayajulu hwfn_index, rval);
13411e25f0dSDavid C Somayajulu
13511e25f0dSDavid C Somayajulu ecore_ptt_release(p_hwfn, p_ptt);
13611e25f0dSDavid C Somayajulu
13711e25f0dSDavid C Somayajulu return (rval);
13811e25f0dSDavid C Somayajulu }
13911e25f0dSDavid C Somayajulu
14011e25f0dSDavid C Somayajulu static void
qlnx_get_grc_dump_size(qlnx_host_t * ha,qlnx_grcdump_t * grcdump)14111e25f0dSDavid C Somayajulu qlnx_get_grc_dump_size(qlnx_host_t *ha, qlnx_grcdump_t *grcdump)
14211e25f0dSDavid C Somayajulu {
14311e25f0dSDavid C Somayajulu int i;
14411e25f0dSDavid C Somayajulu
14511e25f0dSDavid C Somayajulu grcdump->pci_func = ha->pci_func;
14611e25f0dSDavid C Somayajulu
14711e25f0dSDavid C Somayajulu for (i = 0; i < ha->cdev.num_hwfns; i++)
14811e25f0dSDavid C Somayajulu grcdump->grcdump_size[i] = ha->grcdump_size[i];
14911e25f0dSDavid C Somayajulu
15011e25f0dSDavid C Somayajulu return;
15111e25f0dSDavid C Somayajulu }
15211e25f0dSDavid C Somayajulu
15311e25f0dSDavid C Somayajulu static int
qlnx_get_grc_dump(qlnx_host_t * ha,qlnx_grcdump_t * grcdump)15411e25f0dSDavid C Somayajulu qlnx_get_grc_dump(qlnx_host_t *ha, qlnx_grcdump_t *grcdump)
15511e25f0dSDavid C Somayajulu {
15611e25f0dSDavid C Somayajulu int i;
15711e25f0dSDavid C Somayajulu int rval = 0;
15811e25f0dSDavid C Somayajulu uint32_t dwords = 0;
15911e25f0dSDavid C Somayajulu
16011e25f0dSDavid C Somayajulu grcdump->pci_func = ha->pci_func;
16111e25f0dSDavid C Somayajulu
16211e25f0dSDavid C Somayajulu for (i = 0; i < ha->cdev.num_hwfns; i++) {
16311e25f0dSDavid C Somayajulu if ((ha->grcdump[i] == NULL) || (grcdump->grcdump[i] == NULL) ||
16411e25f0dSDavid C Somayajulu (grcdump->grcdump_size[i] < ha->grcdump_size[i]))
16511e25f0dSDavid C Somayajulu return (EINVAL);
16611e25f0dSDavid C Somayajulu
16711e25f0dSDavid C Somayajulu rval = qlnx_grc_dump(ha, &dwords, i);
16811e25f0dSDavid C Somayajulu
16911e25f0dSDavid C Somayajulu if (rval)
17011e25f0dSDavid C Somayajulu break;
17111e25f0dSDavid C Somayajulu
17211e25f0dSDavid C Somayajulu grcdump->grcdump_dwords[i] = dwords;
17311e25f0dSDavid C Somayajulu
1747a377fbeSDavid C Somayajulu QL_DPRINT1(ha,"grcdump_dwords[%d] = 0x%x\n", i, dwords);
17511e25f0dSDavid C Somayajulu
17611e25f0dSDavid C Somayajulu rval = copyout(ha->grcdump[i], grcdump->grcdump[i],
17711e25f0dSDavid C Somayajulu ha->grcdump_size[i]);
17811e25f0dSDavid C Somayajulu
17911e25f0dSDavid C Somayajulu if (rval)
18011e25f0dSDavid C Somayajulu break;
18111e25f0dSDavid C Somayajulu
18211e25f0dSDavid C Somayajulu ha->grcdump_dwords[i] = 0;
18311e25f0dSDavid C Somayajulu }
18411e25f0dSDavid C Somayajulu
18511e25f0dSDavid C Somayajulu ha->grcdump_taken = 0;
18611e25f0dSDavid C Somayajulu
18711e25f0dSDavid C Somayajulu return (rval);
18811e25f0dSDavid C Somayajulu }
18911e25f0dSDavid C Somayajulu
19011e25f0dSDavid C Somayajulu int
qlnx_idle_chk(qlnx_host_t * ha,uint32_t * num_dumped_dwords,int hwfn_index)19111e25f0dSDavid C Somayajulu qlnx_idle_chk(qlnx_host_t *ha, uint32_t *num_dumped_dwords, int hwfn_index)
19211e25f0dSDavid C Somayajulu {
19311e25f0dSDavid C Somayajulu int rval = EINVAL;
19411e25f0dSDavid C Somayajulu struct ecore_hwfn *p_hwfn;
19511e25f0dSDavid C Somayajulu struct ecore_ptt *p_ptt;
19611e25f0dSDavid C Somayajulu
19711e25f0dSDavid C Somayajulu if (ha->idle_chk_dwords[hwfn_index]) {
19811e25f0dSDavid C Somayajulu /* the idle check is already available */
19911e25f0dSDavid C Somayajulu *num_dumped_dwords = ha->idle_chk_dwords[hwfn_index];
20011e25f0dSDavid C Somayajulu return (0);
20111e25f0dSDavid C Somayajulu }
20211e25f0dSDavid C Somayajulu
20311e25f0dSDavid C Somayajulu ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver());
20411e25f0dSDavid C Somayajulu
20511e25f0dSDavid C Somayajulu p_hwfn = &ha->cdev.hwfns[hwfn_index];
20611e25f0dSDavid C Somayajulu p_ptt = ecore_ptt_acquire(p_hwfn);
20711e25f0dSDavid C Somayajulu
20811e25f0dSDavid C Somayajulu if (!p_ptt) {
2097a377fbeSDavid C Somayajulu QL_DPRINT1(ha,"ecore_ptt_acquire failed\n");
21011e25f0dSDavid C Somayajulu return (rval);
21111e25f0dSDavid C Somayajulu }
21211e25f0dSDavid C Somayajulu
21311e25f0dSDavid C Somayajulu if ((rval = ecore_dbg_idle_chk_dump(p_hwfn, p_ptt,
21411e25f0dSDavid C Somayajulu ha->idle_chk[hwfn_index],
21511e25f0dSDavid C Somayajulu (ha->idle_chk_size[hwfn_index] >> 2),
21611e25f0dSDavid C Somayajulu num_dumped_dwords)) == DBG_STATUS_OK) {
21711e25f0dSDavid C Somayajulu rval = 0;
21811e25f0dSDavid C Somayajulu ha->idle_chk_taken = 1;
21911e25f0dSDavid C Somayajulu } else
2207a377fbeSDavid C Somayajulu QL_DPRINT1(ha,"ecore_dbg_idle_chk_dump failed [%d, 0x%x]\n",
2217a377fbeSDavid C Somayajulu hwfn_index, rval);
22211e25f0dSDavid C Somayajulu
22311e25f0dSDavid C Somayajulu ecore_ptt_release(p_hwfn, p_ptt);
22411e25f0dSDavid C Somayajulu
22511e25f0dSDavid C Somayajulu return (rval);
22611e25f0dSDavid C Somayajulu }
22711e25f0dSDavid C Somayajulu
22811e25f0dSDavid C Somayajulu static void
qlnx_get_idle_chk_size(qlnx_host_t * ha,qlnx_idle_chk_t * idle_chk)22911e25f0dSDavid C Somayajulu qlnx_get_idle_chk_size(qlnx_host_t *ha, qlnx_idle_chk_t *idle_chk)
23011e25f0dSDavid C Somayajulu {
23111e25f0dSDavid C Somayajulu int i;
23211e25f0dSDavid C Somayajulu
23311e25f0dSDavid C Somayajulu idle_chk->pci_func = ha->pci_func;
23411e25f0dSDavid C Somayajulu
23511e25f0dSDavid C Somayajulu for (i = 0; i < ha->cdev.num_hwfns; i++)
23611e25f0dSDavid C Somayajulu idle_chk->idle_chk_size[i] = ha->idle_chk_size[i];
23711e25f0dSDavid C Somayajulu
23811e25f0dSDavid C Somayajulu return;
23911e25f0dSDavid C Somayajulu }
24011e25f0dSDavid C Somayajulu
24111e25f0dSDavid C Somayajulu static int
qlnx_get_idle_chk(qlnx_host_t * ha,qlnx_idle_chk_t * idle_chk)24211e25f0dSDavid C Somayajulu qlnx_get_idle_chk(qlnx_host_t *ha, qlnx_idle_chk_t *idle_chk)
24311e25f0dSDavid C Somayajulu {
24411e25f0dSDavid C Somayajulu int i;
24511e25f0dSDavid C Somayajulu int rval = 0;
24611e25f0dSDavid C Somayajulu uint32_t dwords = 0;
24711e25f0dSDavid C Somayajulu
24811e25f0dSDavid C Somayajulu idle_chk->pci_func = ha->pci_func;
24911e25f0dSDavid C Somayajulu
25011e25f0dSDavid C Somayajulu for (i = 0; i < ha->cdev.num_hwfns; i++) {
25111e25f0dSDavid C Somayajulu if ((ha->idle_chk[i] == NULL) ||
25211e25f0dSDavid C Somayajulu (idle_chk->idle_chk[i] == NULL) ||
25311e25f0dSDavid C Somayajulu (idle_chk->idle_chk_size[i] <
25411e25f0dSDavid C Somayajulu ha->idle_chk_size[i]))
25511e25f0dSDavid C Somayajulu return (EINVAL);
25611e25f0dSDavid C Somayajulu
25711e25f0dSDavid C Somayajulu rval = qlnx_idle_chk(ha, &dwords, i);
25811e25f0dSDavid C Somayajulu
25911e25f0dSDavid C Somayajulu if (rval)
26011e25f0dSDavid C Somayajulu break;
26111e25f0dSDavid C Somayajulu
26211e25f0dSDavid C Somayajulu idle_chk->idle_chk_dwords[i] = dwords;
26311e25f0dSDavid C Somayajulu
2647a377fbeSDavid C Somayajulu QL_DPRINT1(ha,"idle_chk_dwords[%d] = 0x%x\n", i, dwords);
26511e25f0dSDavid C Somayajulu
26611e25f0dSDavid C Somayajulu rval = copyout(ha->idle_chk[i], idle_chk->idle_chk[i],
26711e25f0dSDavid C Somayajulu ha->idle_chk_size[i]);
26811e25f0dSDavid C Somayajulu
26911e25f0dSDavid C Somayajulu if (rval)
27011e25f0dSDavid C Somayajulu break;
27111e25f0dSDavid C Somayajulu
27211e25f0dSDavid C Somayajulu ha->idle_chk_dwords[i] = 0;
27311e25f0dSDavid C Somayajulu }
27411e25f0dSDavid C Somayajulu ha->idle_chk_taken = 0;
27511e25f0dSDavid C Somayajulu
27611e25f0dSDavid C Somayajulu return (rval);
27711e25f0dSDavid C Somayajulu }
27811e25f0dSDavid C Somayajulu
27911e25f0dSDavid C Somayajulu static uint32_t
qlnx_get_trace_cmd_size(qlnx_host_t * ha,int hwfn_index,uint16_t cmd)28011e25f0dSDavid C Somayajulu qlnx_get_trace_cmd_size(qlnx_host_t *ha, int hwfn_index, uint16_t cmd)
28111e25f0dSDavid C Somayajulu {
28211e25f0dSDavid C Somayajulu int rval = -1;
28311e25f0dSDavid C Somayajulu struct ecore_hwfn *p_hwfn;
28411e25f0dSDavid C Somayajulu struct ecore_ptt *p_ptt;
28511e25f0dSDavid C Somayajulu uint32_t num_dwords = 0;
28611e25f0dSDavid C Somayajulu
28711e25f0dSDavid C Somayajulu p_hwfn = &ha->cdev.hwfns[hwfn_index];
28811e25f0dSDavid C Somayajulu p_ptt = ecore_ptt_acquire(p_hwfn);
28911e25f0dSDavid C Somayajulu
29011e25f0dSDavid C Somayajulu if (!p_ptt) {
2917a377fbeSDavid C Somayajulu QL_DPRINT1(ha, "ecore_ptt_acquire [%d, 0x%x]failed\n",
2927a377fbeSDavid C Somayajulu hwfn_index, cmd);
29311e25f0dSDavid C Somayajulu return (0);
29411e25f0dSDavid C Somayajulu }
29511e25f0dSDavid C Somayajulu
29611e25f0dSDavid C Somayajulu switch (cmd) {
29711e25f0dSDavid C Somayajulu case QLNX_MCP_TRACE:
29811e25f0dSDavid C Somayajulu rval = ecore_dbg_mcp_trace_get_dump_buf_size(p_hwfn,
29911e25f0dSDavid C Somayajulu p_ptt, &num_dwords);
30011e25f0dSDavid C Somayajulu break;
30111e25f0dSDavid C Somayajulu
30211e25f0dSDavid C Somayajulu case QLNX_REG_FIFO:
30311e25f0dSDavid C Somayajulu rval = ecore_dbg_reg_fifo_get_dump_buf_size(p_hwfn,
30411e25f0dSDavid C Somayajulu p_ptt, &num_dwords);
30511e25f0dSDavid C Somayajulu break;
30611e25f0dSDavid C Somayajulu
30711e25f0dSDavid C Somayajulu case QLNX_IGU_FIFO:
30811e25f0dSDavid C Somayajulu rval = ecore_dbg_igu_fifo_get_dump_buf_size(p_hwfn,
30911e25f0dSDavid C Somayajulu p_ptt, &num_dwords);
31011e25f0dSDavid C Somayajulu break;
31111e25f0dSDavid C Somayajulu
31211e25f0dSDavid C Somayajulu case QLNX_PROTECTION_OVERRIDE:
31311e25f0dSDavid C Somayajulu rval = ecore_dbg_protection_override_get_dump_buf_size(p_hwfn,
31411e25f0dSDavid C Somayajulu p_ptt, &num_dwords);
31511e25f0dSDavid C Somayajulu break;
31611e25f0dSDavid C Somayajulu
31711e25f0dSDavid C Somayajulu case QLNX_FW_ASSERTS:
31811e25f0dSDavid C Somayajulu rval = ecore_dbg_fw_asserts_get_dump_buf_size(p_hwfn,
31911e25f0dSDavid C Somayajulu p_ptt, &num_dwords);
32011e25f0dSDavid C Somayajulu break;
32111e25f0dSDavid C Somayajulu }
32211e25f0dSDavid C Somayajulu
32311e25f0dSDavid C Somayajulu if (rval != DBG_STATUS_OK) {
3247a377fbeSDavid C Somayajulu QL_DPRINT1(ha,"cmd = 0x%x failed [0x%x]\n", cmd, rval);
32511e25f0dSDavid C Somayajulu num_dwords = 0;
32611e25f0dSDavid C Somayajulu }
32711e25f0dSDavid C Somayajulu
32811e25f0dSDavid C Somayajulu ecore_ptt_release(p_hwfn, p_ptt);
32911e25f0dSDavid C Somayajulu
33011e25f0dSDavid C Somayajulu return ((num_dwords * sizeof (uint32_t)));
33111e25f0dSDavid C Somayajulu }
33211e25f0dSDavid C Somayajulu
33311e25f0dSDavid C Somayajulu static void
qlnx_get_trace_size(qlnx_host_t * ha,qlnx_trace_t * trace)33411e25f0dSDavid C Somayajulu qlnx_get_trace_size(qlnx_host_t *ha, qlnx_trace_t *trace)
33511e25f0dSDavid C Somayajulu {
33611e25f0dSDavid C Somayajulu int i;
33711e25f0dSDavid C Somayajulu
33811e25f0dSDavid C Somayajulu trace->pci_func = ha->pci_func;
33911e25f0dSDavid C Somayajulu
34011e25f0dSDavid C Somayajulu for (i = 0; i < ha->cdev.num_hwfns; i++) {
34111e25f0dSDavid C Somayajulu trace->size[i] = qlnx_get_trace_cmd_size(ha, i, trace->cmd);
34211e25f0dSDavid C Somayajulu }
34311e25f0dSDavid C Somayajulu
34411e25f0dSDavid C Somayajulu return;
34511e25f0dSDavid C Somayajulu }
34611e25f0dSDavid C Somayajulu
34711e25f0dSDavid C Somayajulu static int
qlnx_get_trace(qlnx_host_t * ha,int hwfn_index,qlnx_trace_t * trace)34811e25f0dSDavid C Somayajulu qlnx_get_trace(qlnx_host_t *ha, int hwfn_index, qlnx_trace_t *trace)
34911e25f0dSDavid C Somayajulu {
35011e25f0dSDavid C Somayajulu int rval = -1;
35111e25f0dSDavid C Somayajulu struct ecore_hwfn *p_hwfn;
35211e25f0dSDavid C Somayajulu struct ecore_ptt *p_ptt;
35311e25f0dSDavid C Somayajulu uint32_t num_dwords = 0;
35411e25f0dSDavid C Somayajulu void *buffer;
35511e25f0dSDavid C Somayajulu
35611e25f0dSDavid C Somayajulu buffer = qlnx_zalloc(trace->size[hwfn_index]);
35711e25f0dSDavid C Somayajulu if (buffer == NULL) {
3587a377fbeSDavid C Somayajulu QL_DPRINT1(ha,"qlnx_zalloc [%d, 0x%x]failed\n",
3597a377fbeSDavid C Somayajulu hwfn_index, trace->cmd);
36011e25f0dSDavid C Somayajulu return (ENXIO);
36111e25f0dSDavid C Somayajulu }
36211e25f0dSDavid C Somayajulu ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver());
36311e25f0dSDavid C Somayajulu
36411e25f0dSDavid C Somayajulu p_hwfn = &ha->cdev.hwfns[hwfn_index];
36511e25f0dSDavid C Somayajulu p_ptt = ecore_ptt_acquire(p_hwfn);
36611e25f0dSDavid C Somayajulu
36711e25f0dSDavid C Somayajulu if (!p_ptt) {
3687a377fbeSDavid C Somayajulu QL_DPRINT1(ha, "ecore_ptt_acquire [%d, 0x%x]failed\n",
3697a377fbeSDavid C Somayajulu hwfn_index, trace->cmd);
37011e25f0dSDavid C Somayajulu return (ENXIO);
37111e25f0dSDavid C Somayajulu }
37211e25f0dSDavid C Somayajulu
37311e25f0dSDavid C Somayajulu switch (trace->cmd) {
37411e25f0dSDavid C Somayajulu case QLNX_MCP_TRACE:
37511e25f0dSDavid C Somayajulu rval = ecore_dbg_mcp_trace_dump(p_hwfn, p_ptt,
37611e25f0dSDavid C Somayajulu buffer, (trace->size[hwfn_index] >> 2),
37711e25f0dSDavid C Somayajulu &num_dwords);
37811e25f0dSDavid C Somayajulu break;
37911e25f0dSDavid C Somayajulu
38011e25f0dSDavid C Somayajulu case QLNX_REG_FIFO:
38111e25f0dSDavid C Somayajulu rval = ecore_dbg_reg_fifo_dump(p_hwfn, p_ptt,
38211e25f0dSDavid C Somayajulu buffer, (trace->size[hwfn_index] >> 2),
38311e25f0dSDavid C Somayajulu &num_dwords);
38411e25f0dSDavid C Somayajulu break;
38511e25f0dSDavid C Somayajulu
38611e25f0dSDavid C Somayajulu case QLNX_IGU_FIFO:
38711e25f0dSDavid C Somayajulu rval = ecore_dbg_igu_fifo_dump(p_hwfn, p_ptt,
38811e25f0dSDavid C Somayajulu buffer, (trace->size[hwfn_index] >> 2),
38911e25f0dSDavid C Somayajulu &num_dwords);
39011e25f0dSDavid C Somayajulu break;
39111e25f0dSDavid C Somayajulu
39211e25f0dSDavid C Somayajulu case QLNX_PROTECTION_OVERRIDE:
39311e25f0dSDavid C Somayajulu rval = ecore_dbg_protection_override_dump(p_hwfn, p_ptt,
39411e25f0dSDavid C Somayajulu buffer, (trace->size[hwfn_index] >> 2),
39511e25f0dSDavid C Somayajulu &num_dwords);
39611e25f0dSDavid C Somayajulu break;
39711e25f0dSDavid C Somayajulu
39811e25f0dSDavid C Somayajulu case QLNX_FW_ASSERTS:
39911e25f0dSDavid C Somayajulu rval = ecore_dbg_fw_asserts_dump(p_hwfn, p_ptt,
40011e25f0dSDavid C Somayajulu buffer, (trace->size[hwfn_index] >> 2),
40111e25f0dSDavid C Somayajulu &num_dwords);
40211e25f0dSDavid C Somayajulu break;
40311e25f0dSDavid C Somayajulu }
40411e25f0dSDavid C Somayajulu
40511e25f0dSDavid C Somayajulu if (rval != DBG_STATUS_OK) {
4067a377fbeSDavid C Somayajulu QL_DPRINT1(ha,"cmd = 0x%x failed [0x%x]\n", trace->cmd, rval);
40711e25f0dSDavid C Somayajulu num_dwords = 0;
40811e25f0dSDavid C Somayajulu }
40911e25f0dSDavid C Somayajulu
41011e25f0dSDavid C Somayajulu ecore_ptt_release(p_hwfn, p_ptt);
41111e25f0dSDavid C Somayajulu
41211e25f0dSDavid C Somayajulu trace->dwords[hwfn_index] = num_dwords;
41311e25f0dSDavid C Somayajulu
41411e25f0dSDavid C Somayajulu if (num_dwords) {
41511e25f0dSDavid C Somayajulu rval = copyout(buffer, trace->buffer[hwfn_index],
41611e25f0dSDavid C Somayajulu (num_dwords << 2));
41711e25f0dSDavid C Somayajulu }
41811e25f0dSDavid C Somayajulu
41911e25f0dSDavid C Somayajulu return (rval);
42011e25f0dSDavid C Somayajulu }
42111e25f0dSDavid C Somayajulu
42211e25f0dSDavid C Somayajulu static int
qlnx_reg_rd_wr(qlnx_host_t * ha,qlnx_reg_rd_wr_t * reg_rd_wr)42311e25f0dSDavid C Somayajulu qlnx_reg_rd_wr(qlnx_host_t *ha, qlnx_reg_rd_wr_t *reg_rd_wr)
42411e25f0dSDavid C Somayajulu {
42511e25f0dSDavid C Somayajulu int rval = 0;
42611e25f0dSDavid C Somayajulu struct ecore_hwfn *p_hwfn;
42711e25f0dSDavid C Somayajulu
42811e25f0dSDavid C Somayajulu if (reg_rd_wr->hwfn_index >= QLNX_MAX_HW_FUNCS) {
42911e25f0dSDavid C Somayajulu return (EINVAL);
43011e25f0dSDavid C Somayajulu }
43111e25f0dSDavid C Somayajulu
43211e25f0dSDavid C Somayajulu p_hwfn = &ha->cdev.hwfns[reg_rd_wr->hwfn_index];
43311e25f0dSDavid C Somayajulu
43411e25f0dSDavid C Somayajulu switch (reg_rd_wr->cmd) {
43511e25f0dSDavid C Somayajulu case QLNX_REG_READ_CMD:
43611e25f0dSDavid C Somayajulu if (reg_rd_wr->access_type == QLNX_REG_ACCESS_DIRECT) {
43711e25f0dSDavid C Somayajulu reg_rd_wr->val = qlnx_reg_rd32(p_hwfn,
43811e25f0dSDavid C Somayajulu reg_rd_wr->addr);
43911e25f0dSDavid C Somayajulu }
44011e25f0dSDavid C Somayajulu break;
44111e25f0dSDavid C Somayajulu
44211e25f0dSDavid C Somayajulu case QLNX_REG_WRITE_CMD:
44311e25f0dSDavid C Somayajulu if (reg_rd_wr->access_type == QLNX_REG_ACCESS_DIRECT) {
44411e25f0dSDavid C Somayajulu qlnx_reg_wr32(p_hwfn, reg_rd_wr->addr,
44511e25f0dSDavid C Somayajulu reg_rd_wr->val);
44611e25f0dSDavid C Somayajulu }
44711e25f0dSDavid C Somayajulu break;
44811e25f0dSDavid C Somayajulu
44911e25f0dSDavid C Somayajulu default:
45011e25f0dSDavid C Somayajulu rval = EINVAL;
45111e25f0dSDavid C Somayajulu break;
45211e25f0dSDavid C Somayajulu }
45311e25f0dSDavid C Somayajulu
45411e25f0dSDavid C Somayajulu return (rval);
45511e25f0dSDavid C Somayajulu }
45611e25f0dSDavid C Somayajulu
45711e25f0dSDavid C Somayajulu static int
qlnx_rd_wr_pci_config(qlnx_host_t * ha,qlnx_pcicfg_rd_wr_t * pci_cfg_rd_wr)45811e25f0dSDavid C Somayajulu qlnx_rd_wr_pci_config(qlnx_host_t *ha, qlnx_pcicfg_rd_wr_t *pci_cfg_rd_wr)
45911e25f0dSDavid C Somayajulu {
46011e25f0dSDavid C Somayajulu int rval = 0;
46111e25f0dSDavid C Somayajulu
46211e25f0dSDavid C Somayajulu switch (pci_cfg_rd_wr->cmd) {
46311e25f0dSDavid C Somayajulu case QLNX_PCICFG_READ:
46411e25f0dSDavid C Somayajulu pci_cfg_rd_wr->val = pci_read_config(ha->pci_dev,
46511e25f0dSDavid C Somayajulu pci_cfg_rd_wr->reg,
46611e25f0dSDavid C Somayajulu pci_cfg_rd_wr->width);
46711e25f0dSDavid C Somayajulu break;
46811e25f0dSDavid C Somayajulu
46911e25f0dSDavid C Somayajulu case QLNX_PCICFG_WRITE:
47011e25f0dSDavid C Somayajulu pci_write_config(ha->pci_dev, pci_cfg_rd_wr->reg,
47111e25f0dSDavid C Somayajulu pci_cfg_rd_wr->val, pci_cfg_rd_wr->width);
47211e25f0dSDavid C Somayajulu break;
47311e25f0dSDavid C Somayajulu
47411e25f0dSDavid C Somayajulu default:
47511e25f0dSDavid C Somayajulu rval = EINVAL;
47611e25f0dSDavid C Somayajulu break;
47711e25f0dSDavid C Somayajulu }
47811e25f0dSDavid C Somayajulu
47911e25f0dSDavid C Somayajulu return (rval);
48011e25f0dSDavid C Somayajulu }
48111e25f0dSDavid C Somayajulu
48211e25f0dSDavid C Somayajulu static void
qlnx_mac_addr(qlnx_host_t * ha,qlnx_perm_mac_addr_t * mac_addr)48311e25f0dSDavid C Somayajulu qlnx_mac_addr(qlnx_host_t *ha, qlnx_perm_mac_addr_t *mac_addr)
48411e25f0dSDavid C Somayajulu {
48511e25f0dSDavid C Somayajulu bzero(mac_addr->addr, sizeof(mac_addr->addr));
48611e25f0dSDavid C Somayajulu snprintf(mac_addr->addr, sizeof(mac_addr->addr),
48711e25f0dSDavid C Somayajulu "%02x:%02x:%02x:%02x:%02x:%02x",
48811e25f0dSDavid C Somayajulu ha->primary_mac[0], ha->primary_mac[1], ha->primary_mac[2],
48911e25f0dSDavid C Somayajulu ha->primary_mac[3], ha->primary_mac[4], ha->primary_mac[5]);
49011e25f0dSDavid C Somayajulu
49111e25f0dSDavid C Somayajulu return;
49211e25f0dSDavid C Somayajulu }
49311e25f0dSDavid C Somayajulu
49411e25f0dSDavid C Somayajulu static int
qlnx_get_regs(qlnx_host_t * ha,qlnx_get_regs_t * regs)49511e25f0dSDavid C Somayajulu qlnx_get_regs(qlnx_host_t *ha, qlnx_get_regs_t *regs)
49611e25f0dSDavid C Somayajulu {
49711e25f0dSDavid C Somayajulu int i;
49811e25f0dSDavid C Somayajulu int rval = 0;
49911e25f0dSDavid C Somayajulu uint32_t dwords = 0;
50011e25f0dSDavid C Somayajulu uint8_t *outb;
50111e25f0dSDavid C Somayajulu
50211e25f0dSDavid C Somayajulu regs->reg_buf_len = 0;
50311e25f0dSDavid C Somayajulu outb = regs->reg_buf;
50411e25f0dSDavid C Somayajulu
50511e25f0dSDavid C Somayajulu for (i = 0; i < ha->cdev.num_hwfns; i++) {
50611e25f0dSDavid C Somayajulu rval = qlnx_grc_dump(ha, &dwords, i);
50711e25f0dSDavid C Somayajulu
50811e25f0dSDavid C Somayajulu if (rval)
50911e25f0dSDavid C Somayajulu break;
51011e25f0dSDavid C Somayajulu
51111e25f0dSDavid C Somayajulu regs->reg_buf_len += (dwords << 2);
51211e25f0dSDavid C Somayajulu
51311e25f0dSDavid C Somayajulu rval = copyout(ha->grcdump[i], outb, ha->grcdump_size[i]);
51411e25f0dSDavid C Somayajulu
51511e25f0dSDavid C Somayajulu if (rval)
51611e25f0dSDavid C Somayajulu break;
51711e25f0dSDavid C Somayajulu
51811e25f0dSDavid C Somayajulu ha->grcdump_dwords[i] = 0;
51911e25f0dSDavid C Somayajulu outb += regs->reg_buf_len;
52011e25f0dSDavid C Somayajulu }
52111e25f0dSDavid C Somayajulu
52211e25f0dSDavid C Somayajulu ha->grcdump_taken = 0;
52311e25f0dSDavid C Somayajulu
52411e25f0dSDavid C Somayajulu return (rval);
52511e25f0dSDavid C Somayajulu }
52611e25f0dSDavid C Somayajulu
527d576ccdfSRyan Libby extern char qlnx_name_str[];
528d576ccdfSRyan Libby extern char qlnx_ver_str[];
529d576ccdfSRyan Libby
53011e25f0dSDavid C Somayajulu static int
qlnx_drv_info(qlnx_host_t * ha,qlnx_drvinfo_t * drv_info)53111e25f0dSDavid C Somayajulu qlnx_drv_info(qlnx_host_t *ha, qlnx_drvinfo_t *drv_info)
53211e25f0dSDavid C Somayajulu {
53311e25f0dSDavid C Somayajulu int i;
53411e25f0dSDavid C Somayajulu
53511e25f0dSDavid C Somayajulu bzero(drv_info, sizeof(qlnx_drvinfo_t));
53611e25f0dSDavid C Somayajulu
53711e25f0dSDavid C Somayajulu snprintf(drv_info->drv_name, sizeof(drv_info->drv_name), "%s",
53811e25f0dSDavid C Somayajulu qlnx_name_str);
53911e25f0dSDavid C Somayajulu snprintf(drv_info->drv_version, sizeof(drv_info->drv_version), "%s",
54011e25f0dSDavid C Somayajulu qlnx_ver_str);
54111e25f0dSDavid C Somayajulu snprintf(drv_info->mfw_version, sizeof(drv_info->mfw_version), "%s",
54211e25f0dSDavid C Somayajulu ha->mfw_ver);
54311e25f0dSDavid C Somayajulu snprintf(drv_info->stormfw_version, sizeof(drv_info->stormfw_version),
54411e25f0dSDavid C Somayajulu "%s", ha->stormfw_ver);
54511e25f0dSDavid C Somayajulu
54611e25f0dSDavid C Somayajulu drv_info->eeprom_dump_len = ha->flash_size;
54711e25f0dSDavid C Somayajulu
54811e25f0dSDavid C Somayajulu for (i = 0; i < ha->cdev.num_hwfns; i++) {
54911e25f0dSDavid C Somayajulu drv_info->reg_dump_len += ha->grcdump_size[i];
55011e25f0dSDavid C Somayajulu }
55111e25f0dSDavid C Somayajulu
55211e25f0dSDavid C Somayajulu snprintf(drv_info->bus_info, sizeof(drv_info->bus_info),
55311e25f0dSDavid C Somayajulu "%d:%d:%d", pci_get_bus(ha->pci_dev),
55411e25f0dSDavid C Somayajulu pci_get_slot(ha->pci_dev), ha->pci_func);
55511e25f0dSDavid C Somayajulu
55611e25f0dSDavid C Somayajulu return (0);
55711e25f0dSDavid C Somayajulu }
55811e25f0dSDavid C Somayajulu
55911e25f0dSDavid C Somayajulu static int
qlnx_dev_settings(qlnx_host_t * ha,qlnx_dev_setting_t * dev_info)56011e25f0dSDavid C Somayajulu qlnx_dev_settings(qlnx_host_t *ha, qlnx_dev_setting_t *dev_info)
56111e25f0dSDavid C Somayajulu {
56211e25f0dSDavid C Somayajulu struct ecore_hwfn *p_hwfn;
56311e25f0dSDavid C Somayajulu struct qlnx_link_output if_link;
56411e25f0dSDavid C Somayajulu
56511e25f0dSDavid C Somayajulu p_hwfn = &ha->cdev.hwfns[0];
56611e25f0dSDavid C Somayajulu
567217ec208SDavid C Somayajulu qlnx_fill_link(ha, p_hwfn, &if_link);
56811e25f0dSDavid C Somayajulu
56911e25f0dSDavid C Somayajulu dev_info->supported = if_link.supported_caps;
57011e25f0dSDavid C Somayajulu dev_info->advertising = if_link.advertised_caps;
57111e25f0dSDavid C Somayajulu dev_info->speed = if_link.speed;
57211e25f0dSDavid C Somayajulu dev_info->duplex = if_link.duplex;
57311e25f0dSDavid C Somayajulu dev_info->port = ha->pci_func & 0x1;
57411e25f0dSDavid C Somayajulu dev_info->autoneg = if_link.autoneg;
57511e25f0dSDavid C Somayajulu
57611e25f0dSDavid C Somayajulu return (0);
57711e25f0dSDavid C Somayajulu }
57811e25f0dSDavid C Somayajulu
57911e25f0dSDavid C Somayajulu static int
qlnx_write_nvram(qlnx_host_t * ha,qlnx_nvram_t * nvram,uint32_t cmd)58011e25f0dSDavid C Somayajulu qlnx_write_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram, uint32_t cmd)
58111e25f0dSDavid C Somayajulu {
58211e25f0dSDavid C Somayajulu uint8_t *buf;
58311e25f0dSDavid C Somayajulu int ret = 0;
58411e25f0dSDavid C Somayajulu
58511e25f0dSDavid C Somayajulu if ((nvram->data == NULL) || (nvram->data_len == 0))
58611e25f0dSDavid C Somayajulu return (EINVAL);
58711e25f0dSDavid C Somayajulu
58811e25f0dSDavid C Somayajulu buf = qlnx_zalloc(nvram->data_len);
58911e25f0dSDavid C Somayajulu
59011e25f0dSDavid C Somayajulu ret = copyin(nvram->data, buf, nvram->data_len);
59111e25f0dSDavid C Somayajulu
5927a377fbeSDavid C Somayajulu QL_DPRINT9(ha, "issue cmd = 0x%x data = %p \
5937a377fbeSDavid C Somayajulu data_len = 0x%x ret = 0x%x exit\n",
5947a377fbeSDavid C Somayajulu cmd, nvram->data, nvram->data_len, ret);
59511e25f0dSDavid C Somayajulu
59611e25f0dSDavid C Somayajulu if (ret == 0) {
59711e25f0dSDavid C Somayajulu ret = ecore_mcp_nvm_write(&ha->cdev, cmd,
59811e25f0dSDavid C Somayajulu nvram->offset, buf, nvram->data_len);
59911e25f0dSDavid C Somayajulu }
60011e25f0dSDavid C Somayajulu
6017a377fbeSDavid C Somayajulu QL_DPRINT9(ha, "cmd = 0x%x data = %p \
6027a377fbeSDavid C Somayajulu data_len = 0x%x resp = 0x%x ret = 0x%x exit\n",
6037a377fbeSDavid C Somayajulu cmd, nvram->data, nvram->data_len, ha->cdev.mcp_nvm_resp, ret);
60411e25f0dSDavid C Somayajulu
60511e25f0dSDavid C Somayajulu free(buf, M_QLNXBUF);
60611e25f0dSDavid C Somayajulu
60711e25f0dSDavid C Somayajulu return (ret);
60811e25f0dSDavid C Somayajulu }
60911e25f0dSDavid C Somayajulu
61011e25f0dSDavid C Somayajulu static int
qlnx_read_nvram(qlnx_host_t * ha,qlnx_nvram_t * nvram)61111e25f0dSDavid C Somayajulu qlnx_read_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram)
61211e25f0dSDavid C Somayajulu {
61311e25f0dSDavid C Somayajulu uint8_t *buf;
61411e25f0dSDavid C Somayajulu int ret = 0;
61511e25f0dSDavid C Somayajulu
61611e25f0dSDavid C Somayajulu if ((nvram->data == NULL) || (nvram->data_len == 0))
61711e25f0dSDavid C Somayajulu return (EINVAL);
61811e25f0dSDavid C Somayajulu
61911e25f0dSDavid C Somayajulu buf = qlnx_zalloc(nvram->data_len);
62011e25f0dSDavid C Somayajulu
62111e25f0dSDavid C Somayajulu ret = ecore_mcp_nvm_read(&ha->cdev, nvram->offset, buf,
62211e25f0dSDavid C Somayajulu nvram->data_len);
62311e25f0dSDavid C Somayajulu
6247a377fbeSDavid C Somayajulu QL_DPRINT9(ha, " data = %p data_len = 0x%x \
6257a377fbeSDavid C Somayajulu resp = 0x%x ret = 0x%x exit\n",
6267a377fbeSDavid C Somayajulu nvram->data, nvram->data_len, ha->cdev.mcp_nvm_resp, ret);
62711e25f0dSDavid C Somayajulu
62811e25f0dSDavid C Somayajulu if (ret == 0) {
62911e25f0dSDavid C Somayajulu ret = copyout(buf, nvram->data, nvram->data_len);
63011e25f0dSDavid C Somayajulu }
63111e25f0dSDavid C Somayajulu
63211e25f0dSDavid C Somayajulu free(buf, M_QLNXBUF);
63311e25f0dSDavid C Somayajulu
63411e25f0dSDavid C Somayajulu return (ret);
63511e25f0dSDavid C Somayajulu }
63611e25f0dSDavid C Somayajulu
63711e25f0dSDavid C Somayajulu static int
qlnx_get_nvram_resp(qlnx_host_t * ha,qlnx_nvram_t * nvram)63811e25f0dSDavid C Somayajulu qlnx_get_nvram_resp(qlnx_host_t *ha, qlnx_nvram_t *nvram)
63911e25f0dSDavid C Somayajulu {
64011e25f0dSDavid C Somayajulu uint8_t *buf;
64111e25f0dSDavid C Somayajulu int ret = 0;
64211e25f0dSDavid C Somayajulu
64311e25f0dSDavid C Somayajulu if ((nvram->data == NULL) || (nvram->data_len == 0))
64411e25f0dSDavid C Somayajulu return (EINVAL);
64511e25f0dSDavid C Somayajulu
64611e25f0dSDavid C Somayajulu buf = qlnx_zalloc(nvram->data_len);
64711e25f0dSDavid C Somayajulu
64811e25f0dSDavid C Somayajulu ret = ecore_mcp_nvm_resp(&ha->cdev, buf);
64911e25f0dSDavid C Somayajulu
6507a377fbeSDavid C Somayajulu QL_DPRINT9(ha, "data = %p data_len = 0x%x \
6517a377fbeSDavid C Somayajulu resp = 0x%x ret = 0x%x exit\n",
6527a377fbeSDavid C Somayajulu nvram->data, nvram->data_len, ha->cdev.mcp_nvm_resp, ret);
65311e25f0dSDavid C Somayajulu
65411e25f0dSDavid C Somayajulu if (ret == 0) {
65511e25f0dSDavid C Somayajulu ret = copyout(buf, nvram->data, nvram->data_len);
65611e25f0dSDavid C Somayajulu }
65711e25f0dSDavid C Somayajulu
65811e25f0dSDavid C Somayajulu free(buf, M_QLNXBUF);
65911e25f0dSDavid C Somayajulu
66011e25f0dSDavid C Somayajulu return (ret);
66111e25f0dSDavid C Somayajulu }
66211e25f0dSDavid C Somayajulu
66311e25f0dSDavid C Somayajulu static int
qlnx_nvram(qlnx_host_t * ha,qlnx_nvram_t * nvram)66411e25f0dSDavid C Somayajulu qlnx_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram)
66511e25f0dSDavid C Somayajulu {
66611e25f0dSDavid C Somayajulu int ret = 0;
66711e25f0dSDavid C Somayajulu
66811e25f0dSDavid C Somayajulu switch (nvram->cmd) {
66911e25f0dSDavid C Somayajulu case QLNX_NVRAM_CMD_WRITE_NVRAM:
67011e25f0dSDavid C Somayajulu ret = qlnx_write_nvram(ha, nvram, ECORE_NVM_WRITE_NVRAM);
67111e25f0dSDavid C Somayajulu break;
67211e25f0dSDavid C Somayajulu
67311e25f0dSDavid C Somayajulu case QLNX_NVRAM_CMD_PUT_FILE_DATA:
67411e25f0dSDavid C Somayajulu ret = qlnx_write_nvram(ha, nvram, ECORE_PUT_FILE_DATA);
67511e25f0dSDavid C Somayajulu break;
67611e25f0dSDavid C Somayajulu
67711e25f0dSDavid C Somayajulu case QLNX_NVRAM_CMD_READ_NVRAM:
67811e25f0dSDavid C Somayajulu ret = qlnx_read_nvram(ha, nvram);
67911e25f0dSDavid C Somayajulu break;
68011e25f0dSDavid C Somayajulu
68111e25f0dSDavid C Somayajulu case QLNX_NVRAM_CMD_SET_SECURE_MODE:
68211e25f0dSDavid C Somayajulu ret = ecore_mcp_nvm_set_secure_mode(&ha->cdev, nvram->offset);
68311e25f0dSDavid C Somayajulu
6847a377fbeSDavid C Somayajulu QL_DPRINT9(ha, "QLNX_NVRAM_CMD_SET_SECURE_MODE \
6857a377fbeSDavid C Somayajulu resp = 0x%x ret = 0x%x exit\n",
6867a377fbeSDavid C Somayajulu ha->cdev.mcp_nvm_resp, ret);
68711e25f0dSDavid C Somayajulu break;
68811e25f0dSDavid C Somayajulu
68911e25f0dSDavid C Somayajulu case QLNX_NVRAM_CMD_DEL_FILE:
69011e25f0dSDavid C Somayajulu ret = ecore_mcp_nvm_del_file(&ha->cdev, nvram->offset);
69111e25f0dSDavid C Somayajulu
6927a377fbeSDavid C Somayajulu QL_DPRINT9(ha, "QLNX_NVRAM_CMD_DEL_FILE \
6937a377fbeSDavid C Somayajulu resp = 0x%x ret = 0x%x exit\n",
6947a377fbeSDavid C Somayajulu ha->cdev.mcp_nvm_resp, ret);
69511e25f0dSDavid C Somayajulu break;
69611e25f0dSDavid C Somayajulu
69711e25f0dSDavid C Somayajulu case QLNX_NVRAM_CMD_PUT_FILE_BEGIN:
69811e25f0dSDavid C Somayajulu ret = ecore_mcp_nvm_put_file_begin(&ha->cdev, nvram->offset);
69911e25f0dSDavid C Somayajulu
7007a377fbeSDavid C Somayajulu QL_DPRINT9(ha, "QLNX_NVRAM_CMD_PUT_FILE_BEGIN \
7017a377fbeSDavid C Somayajulu resp = 0x%x ret = 0x%x exit\n",
7027a377fbeSDavid C Somayajulu ha->cdev.mcp_nvm_resp, ret);
70311e25f0dSDavid C Somayajulu break;
70411e25f0dSDavid C Somayajulu
70511e25f0dSDavid C Somayajulu case QLNX_NVRAM_CMD_GET_NVRAM_RESP:
70611e25f0dSDavid C Somayajulu ret = qlnx_get_nvram_resp(ha, nvram);
70711e25f0dSDavid C Somayajulu break;
70811e25f0dSDavid C Somayajulu
70911e25f0dSDavid C Somayajulu default:
71011e25f0dSDavid C Somayajulu ret = EINVAL;
71111e25f0dSDavid C Somayajulu break;
71211e25f0dSDavid C Somayajulu }
71311e25f0dSDavid C Somayajulu
71411e25f0dSDavid C Somayajulu return (ret);
71511e25f0dSDavid C Somayajulu }
71611e25f0dSDavid C Somayajulu
71711e25f0dSDavid C Somayajulu static void
qlnx_storm_stats(qlnx_host_t * ha,qlnx_storm_stats_dump_t * s_stats)71811e25f0dSDavid C Somayajulu qlnx_storm_stats(qlnx_host_t *ha, qlnx_storm_stats_dump_t *s_stats)
71911e25f0dSDavid C Somayajulu {
72011e25f0dSDavid C Somayajulu int i;
72111e25f0dSDavid C Somayajulu int index;
72211e25f0dSDavid C Somayajulu int ret;
72311e25f0dSDavid C Somayajulu int stats_copied = 0;
72411e25f0dSDavid C Somayajulu
72511e25f0dSDavid C Somayajulu s_stats->num_hwfns = ha->cdev.num_hwfns;
72611e25f0dSDavid C Somayajulu
72711e25f0dSDavid C Somayajulu // if (ha->storm_stats_index < QLNX_STORM_STATS_SAMPLES_PER_HWFN)
72811e25f0dSDavid C Somayajulu // return;
72911e25f0dSDavid C Somayajulu
73011e25f0dSDavid C Somayajulu s_stats->num_samples = ha->storm_stats_index;
73111e25f0dSDavid C Somayajulu
73211e25f0dSDavid C Somayajulu for (i = 0; i < ha->cdev.num_hwfns; i++) {
73311e25f0dSDavid C Somayajulu index = (QLNX_STORM_STATS_SAMPLES_PER_HWFN * i);
73411e25f0dSDavid C Somayajulu
73511e25f0dSDavid C Somayajulu if (s_stats->buffer[i]) {
73611e25f0dSDavid C Somayajulu ret = copyout(&ha->storm_stats[index],
73711e25f0dSDavid C Somayajulu s_stats->buffer[i],
73811e25f0dSDavid C Somayajulu QLNX_STORM_STATS_BYTES_PER_HWFN);
73911e25f0dSDavid C Somayajulu if (ret) {
74011e25f0dSDavid C Somayajulu printf("%s [%d]: failed\n", __func__, i);
74111e25f0dSDavid C Somayajulu }
74211e25f0dSDavid C Somayajulu
74311e25f0dSDavid C Somayajulu if (s_stats->num_samples ==
74411e25f0dSDavid C Somayajulu QLNX_STORM_STATS_SAMPLES_PER_HWFN) {
74511e25f0dSDavid C Somayajulu bzero((void *)&ha->storm_stats[i],
74611e25f0dSDavid C Somayajulu QLNX_STORM_STATS_BYTES_PER_HWFN);
74711e25f0dSDavid C Somayajulu
74811e25f0dSDavid C Somayajulu stats_copied = 1;
74911e25f0dSDavid C Somayajulu }
75011e25f0dSDavid C Somayajulu }
75111e25f0dSDavid C Somayajulu }
75211e25f0dSDavid C Somayajulu
75311e25f0dSDavid C Somayajulu if (stats_copied)
75411e25f0dSDavid C Somayajulu ha->storm_stats_index = 0;
75511e25f0dSDavid C Somayajulu
75611e25f0dSDavid C Somayajulu return;
75711e25f0dSDavid C Somayajulu }
75811e25f0dSDavid C Somayajulu
759217ec208SDavid C Somayajulu #ifdef QLNX_USER_LLDP
760217ec208SDavid C Somayajulu
761217ec208SDavid C Somayajulu static int
qlnx_lldp_configure(qlnx_host_t * ha,struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,uint32_t enable)762217ec208SDavid C Somayajulu qlnx_lldp_configure(qlnx_host_t *ha, struct ecore_hwfn *p_hwfn,
763217ec208SDavid C Somayajulu struct ecore_ptt *p_ptt, uint32_t enable)
764217ec208SDavid C Somayajulu {
765217ec208SDavid C Somayajulu int ret = 0;
766217ec208SDavid C Somayajulu uint8_t lldp_mac[6] = {0};
767217ec208SDavid C Somayajulu struct ecore_lldp_config_params lldp_params;
768217ec208SDavid C Somayajulu struct ecore_lldp_sys_tlvs tlv_params;
769217ec208SDavid C Somayajulu
770217ec208SDavid C Somayajulu ret = ecore_mcp_get_lldp_mac(p_hwfn, p_ptt, lldp_mac);
771217ec208SDavid C Somayajulu
772217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
773217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
774217ec208SDavid C Somayajulu "%s: ecore_mcp_get_lldp_mac failed\n", __func__);
775217ec208SDavid C Somayajulu return (-1);
776217ec208SDavid C Somayajulu }
777217ec208SDavid C Somayajulu
778217ec208SDavid C Somayajulu bzero(&lldp_params, sizeof(struct ecore_lldp_config_params));
779217ec208SDavid C Somayajulu bzero(&tlv_params, sizeof(struct ecore_lldp_sys_tlvs));
780217ec208SDavid C Somayajulu
781217ec208SDavid C Somayajulu lldp_params.agent = ECORE_LLDP_NEAREST_BRIDGE;
782217ec208SDavid C Somayajulu lldp_params.tx_interval = 30; //Default value used as suggested by MFW
783217ec208SDavid C Somayajulu lldp_params.tx_hold = 4; //Default value used as suggested by MFW
784217ec208SDavid C Somayajulu lldp_params.tx_credit = 5; //Default value used as suggested by MFW
785217ec208SDavid C Somayajulu lldp_params.rx_enable = enable ? 1 : 0;
786217ec208SDavid C Somayajulu lldp_params.tx_enable = enable ? 1 : 0;
787217ec208SDavid C Somayajulu
788217ec208SDavid C Somayajulu lldp_params.chassis_id_tlv[0] = 0;
789217ec208SDavid C Somayajulu lldp_params.chassis_id_tlv[0] |= (QLNX_LLDP_TYPE_CHASSIS_ID << 1);
790217ec208SDavid C Somayajulu lldp_params.chassis_id_tlv[0] |=
791217ec208SDavid C Somayajulu ((QLNX_LLDP_CHASSIS_ID_SUBTYPE_OCTETS +
792217ec208SDavid C Somayajulu QLNX_LLDP_CHASSIS_ID_MAC_ADDR_LEN) << 8);
793217ec208SDavid C Somayajulu lldp_params.chassis_id_tlv[0] |= (QLNX_LLDP_CHASSIS_ID_SUBTYPE_MAC << 16);
794217ec208SDavid C Somayajulu lldp_params.chassis_id_tlv[0] |= lldp_mac[0] << 24;
795217ec208SDavid C Somayajulu lldp_params.chassis_id_tlv[1] = lldp_mac[1] | (lldp_mac[2] << 8) |
796217ec208SDavid C Somayajulu (lldp_mac[3] << 16) | (lldp_mac[4] << 24);
797217ec208SDavid C Somayajulu lldp_params.chassis_id_tlv[2] = lldp_mac[5];
798217ec208SDavid C Somayajulu
799217ec208SDavid C Somayajulu lldp_params.port_id_tlv[0] = 0;
800217ec208SDavid C Somayajulu lldp_params.port_id_tlv[0] |= (QLNX_LLDP_TYPE_PORT_ID << 1);
801217ec208SDavid C Somayajulu lldp_params.port_id_tlv[0] |=
802217ec208SDavid C Somayajulu ((QLNX_LLDP_PORT_ID_SUBTYPE_OCTETS +
803217ec208SDavid C Somayajulu QLNX_LLDP_PORT_ID_MAC_ADDR_LEN) << 8);
804217ec208SDavid C Somayajulu lldp_params.port_id_tlv[0] |= (QLNX_LLDP_PORT_ID_SUBTYPE_MAC << 16);
805217ec208SDavid C Somayajulu lldp_params.port_id_tlv[0] |= lldp_mac[0] << 24;
806217ec208SDavid C Somayajulu lldp_params.port_id_tlv[1] = lldp_mac[1] | (lldp_mac[2] << 8) |
807217ec208SDavid C Somayajulu (lldp_mac[3] << 16) | (lldp_mac[4] << 24);
808217ec208SDavid C Somayajulu lldp_params.port_id_tlv[2] = lldp_mac[5];
809217ec208SDavid C Somayajulu
810217ec208SDavid C Somayajulu ret = ecore_lldp_set_params(p_hwfn, p_ptt, &lldp_params);
811217ec208SDavid C Somayajulu
812217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
813217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
814217ec208SDavid C Somayajulu "%s: ecore_lldp_set_params failed\n", __func__);
815217ec208SDavid C Somayajulu return (-1);
816217ec208SDavid C Somayajulu }
817217ec208SDavid C Somayajulu
818217ec208SDavid C Somayajulu //If LLDP is disable then disable discard_mandatory_tlv flag
819217ec208SDavid C Somayajulu if (!enable) {
820217ec208SDavid C Somayajulu tlv_params.discard_mandatory_tlv = false;
821217ec208SDavid C Somayajulu tlv_params.buf_size = 0;
822217ec208SDavid C Somayajulu ret = ecore_lldp_set_system_tlvs(p_hwfn, p_ptt, &tlv_params);
823217ec208SDavid C Somayajulu }
824217ec208SDavid C Somayajulu
825217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
826217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
827217ec208SDavid C Somayajulu "%s: ecore_lldp_set_system_tlvs failed\n", __func__);
828217ec208SDavid C Somayajulu }
829217ec208SDavid C Somayajulu
830217ec208SDavid C Somayajulu return (ret);
831217ec208SDavid C Somayajulu }
832217ec208SDavid C Somayajulu
833217ec208SDavid C Somayajulu static int
qlnx_register_default_lldp_tlvs(qlnx_host_t * ha,struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)834217ec208SDavid C Somayajulu qlnx_register_default_lldp_tlvs(qlnx_host_t *ha, struct ecore_hwfn *p_hwfn,
835217ec208SDavid C Somayajulu struct ecore_ptt *p_ptt)
836217ec208SDavid C Somayajulu {
837217ec208SDavid C Somayajulu int ret = 0;
838217ec208SDavid C Somayajulu
839217ec208SDavid C Somayajulu ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
840217ec208SDavid C Somayajulu ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_CHASSIS_ID);
841217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
842217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
843217ec208SDavid C Somayajulu "%s: QLNX_LLDP_TYPE_CHASSIS_ID failed\n", __func__);
844217ec208SDavid C Somayajulu goto qlnx_register_default_lldp_tlvs_exit;
845217ec208SDavid C Somayajulu }
846217ec208SDavid C Somayajulu
847217ec208SDavid C Somayajulu //register Port ID TLV
848217ec208SDavid C Somayajulu ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
849217ec208SDavid C Somayajulu ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_PORT_ID);
850217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
851217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
852217ec208SDavid C Somayajulu "%s: QLNX_LLDP_TYPE_PORT_ID failed\n", __func__);
853217ec208SDavid C Somayajulu goto qlnx_register_default_lldp_tlvs_exit;
854217ec208SDavid C Somayajulu }
855217ec208SDavid C Somayajulu
856217ec208SDavid C Somayajulu //register TTL TLV
857217ec208SDavid C Somayajulu ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
858217ec208SDavid C Somayajulu ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_TTL);
859217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
860217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
861217ec208SDavid C Somayajulu "%s: QLNX_LLDP_TYPE_TTL failed\n", __func__);
862217ec208SDavid C Somayajulu goto qlnx_register_default_lldp_tlvs_exit;
863217ec208SDavid C Somayajulu }
864217ec208SDavid C Somayajulu
865217ec208SDavid C Somayajulu //register Port Description TLV
866217ec208SDavid C Somayajulu ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
867217ec208SDavid C Somayajulu ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_PORT_DESC);
868217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
869217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
870217ec208SDavid C Somayajulu "%s: QLNX_LLDP_TYPE_PORT_DESC failed\n", __func__);
871217ec208SDavid C Somayajulu goto qlnx_register_default_lldp_tlvs_exit;
872217ec208SDavid C Somayajulu }
873217ec208SDavid C Somayajulu
874217ec208SDavid C Somayajulu //register System Name TLV
875217ec208SDavid C Somayajulu ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
876217ec208SDavid C Somayajulu ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_SYS_NAME);
877217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
878217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
879217ec208SDavid C Somayajulu "%s: QLNX_LLDP_TYPE_SYS_NAME failed\n", __func__);
880217ec208SDavid C Somayajulu goto qlnx_register_default_lldp_tlvs_exit;
881217ec208SDavid C Somayajulu }
882217ec208SDavid C Somayajulu
883217ec208SDavid C Somayajulu //register System Description TLV
884217ec208SDavid C Somayajulu ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
885217ec208SDavid C Somayajulu ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_SYS_DESC);
886217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
887217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
888217ec208SDavid C Somayajulu "%s: QLNX_LLDP_TYPE_SYS_DESC failed\n", __func__);
889217ec208SDavid C Somayajulu goto qlnx_register_default_lldp_tlvs_exit;
890217ec208SDavid C Somayajulu }
891217ec208SDavid C Somayajulu
892217ec208SDavid C Somayajulu //register System Capabilities TLV
893217ec208SDavid C Somayajulu ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
894217ec208SDavid C Somayajulu ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_SYS_CAPS);
895217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
896217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
897217ec208SDavid C Somayajulu "%s: QLNX_LLDP_TYPE_SYS_CAPS failed\n", __func__);
898217ec208SDavid C Somayajulu goto qlnx_register_default_lldp_tlvs_exit;
899217ec208SDavid C Somayajulu }
900217ec208SDavid C Somayajulu
901217ec208SDavid C Somayajulu //register Management Address TLV
902217ec208SDavid C Somayajulu ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
903217ec208SDavid C Somayajulu ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_MGMT_ADDR);
904217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
905217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
906217ec208SDavid C Somayajulu "%s: QLNX_LLDP_TYPE_MGMT_ADDR failed\n", __func__);
907217ec208SDavid C Somayajulu goto qlnx_register_default_lldp_tlvs_exit;
908217ec208SDavid C Somayajulu }
909217ec208SDavid C Somayajulu
910217ec208SDavid C Somayajulu //register Organizationally Specific TLVs
911217ec208SDavid C Somayajulu ret = ecore_lldp_register_tlv(p_hwfn, p_ptt,
912217ec208SDavid C Somayajulu ECORE_LLDP_NEAREST_BRIDGE, QLNX_LLDP_TYPE_ORG_SPECIFIC);
913217ec208SDavid C Somayajulu if (ret != ECORE_SUCCESS) {
914217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
915217ec208SDavid C Somayajulu "%s: QLNX_LLDP_TYPE_ORG_SPECIFIC failed\n", __func__);
916217ec208SDavid C Somayajulu }
917217ec208SDavid C Somayajulu
918217ec208SDavid C Somayajulu qlnx_register_default_lldp_tlvs_exit:
919217ec208SDavid C Somayajulu return (ret);
920217ec208SDavid C Somayajulu }
921217ec208SDavid C Somayajulu
922217ec208SDavid C Somayajulu int
qlnx_set_lldp_tlvx(qlnx_host_t * ha,qlnx_lldp_sys_tlvs_t * lldp_tlvs)923217ec208SDavid C Somayajulu qlnx_set_lldp_tlvx(qlnx_host_t *ha, qlnx_lldp_sys_tlvs_t *lldp_tlvs)
924217ec208SDavid C Somayajulu {
925217ec208SDavid C Somayajulu int ret = 0;
926217ec208SDavid C Somayajulu struct ecore_hwfn *p_hwfn;
927217ec208SDavid C Somayajulu struct ecore_ptt *p_ptt;
928217ec208SDavid C Somayajulu struct ecore_lldp_sys_tlvs tlv_params;
929217ec208SDavid C Somayajulu
930217ec208SDavid C Somayajulu p_hwfn = &ha->cdev.hwfns[0];
931217ec208SDavid C Somayajulu p_ptt = ecore_ptt_acquire(p_hwfn);
932217ec208SDavid C Somayajulu
933217ec208SDavid C Somayajulu if (!p_ptt) {
934217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
935217ec208SDavid C Somayajulu "%s: ecore_ptt_acquire failed\n", __func__);
936217ec208SDavid C Somayajulu return (ENXIO);
937217ec208SDavid C Somayajulu }
938217ec208SDavid C Somayajulu
939217ec208SDavid C Somayajulu ret = qlnx_lldp_configure(ha, p_hwfn, p_ptt, 0);
940217ec208SDavid C Somayajulu
941217ec208SDavid C Somayajulu if (ret) {
942217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
943217ec208SDavid C Somayajulu "%s: qlnx_lldp_configure disable failed\n", __func__);
944217ec208SDavid C Somayajulu goto qlnx_set_lldp_tlvx_exit;
945217ec208SDavid C Somayajulu }
946217ec208SDavid C Somayajulu
947217ec208SDavid C Somayajulu ret = qlnx_register_default_lldp_tlvs(ha, p_hwfn, p_ptt);
948217ec208SDavid C Somayajulu
949217ec208SDavid C Somayajulu if (ret) {
950217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
951217ec208SDavid C Somayajulu "%s: qlnx_register_default_lldp_tlvs failed\n",
952217ec208SDavid C Somayajulu __func__);
953217ec208SDavid C Somayajulu goto qlnx_set_lldp_tlvx_exit;
954217ec208SDavid C Somayajulu }
955217ec208SDavid C Somayajulu
956217ec208SDavid C Somayajulu ret = qlnx_lldp_configure(ha, p_hwfn, p_ptt, 1);
957217ec208SDavid C Somayajulu
958217ec208SDavid C Somayajulu if (ret) {
959217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
960217ec208SDavid C Somayajulu "%s: qlnx_lldp_configure enable failed\n", __func__);
961217ec208SDavid C Somayajulu goto qlnx_set_lldp_tlvx_exit;
962217ec208SDavid C Somayajulu }
963217ec208SDavid C Somayajulu
964217ec208SDavid C Somayajulu if (lldp_tlvs != NULL) {
965217ec208SDavid C Somayajulu bzero(&tlv_params, sizeof(struct ecore_lldp_sys_tlvs));
966217ec208SDavid C Somayajulu
967217ec208SDavid C Somayajulu tlv_params.discard_mandatory_tlv =
968217ec208SDavid C Somayajulu (lldp_tlvs->discard_mandatory_tlv ? true: false);
969217ec208SDavid C Somayajulu tlv_params.buf_size = lldp_tlvs->buf_size;
970217ec208SDavid C Somayajulu memcpy(tlv_params.buf, lldp_tlvs->buf, lldp_tlvs->buf_size);
971217ec208SDavid C Somayajulu
972217ec208SDavid C Somayajulu ret = ecore_lldp_set_system_tlvs(p_hwfn, p_ptt, &tlv_params);
973217ec208SDavid C Somayajulu
974217ec208SDavid C Somayajulu if (ret) {
975217ec208SDavid C Somayajulu device_printf(ha->pci_dev,
976217ec208SDavid C Somayajulu "%s: ecore_lldp_set_system_tlvs failed\n",
977217ec208SDavid C Somayajulu __func__);
978217ec208SDavid C Somayajulu }
979217ec208SDavid C Somayajulu }
980217ec208SDavid C Somayajulu qlnx_set_lldp_tlvx_exit:
981217ec208SDavid C Somayajulu
982217ec208SDavid C Somayajulu ecore_ptt_release(p_hwfn, p_ptt);
983217ec208SDavid C Somayajulu return (ret);
984217ec208SDavid C Somayajulu }
985217ec208SDavid C Somayajulu
986217ec208SDavid C Somayajulu #endif /* #ifdef QLNX_USER_LLDP */
98711e25f0dSDavid C Somayajulu
98811e25f0dSDavid C Somayajulu static int
qlnx_eioctl(struct cdev * dev,u_long cmd,caddr_t data,int fflag,struct thread * td)98911e25f0dSDavid C Somayajulu qlnx_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
99011e25f0dSDavid C Somayajulu struct thread *td)
99111e25f0dSDavid C Somayajulu {
99211e25f0dSDavid C Somayajulu qlnx_host_t *ha;
99311e25f0dSDavid C Somayajulu int rval = 0;
99411e25f0dSDavid C Somayajulu qlnx_trace_t *trace;
99511e25f0dSDavid C Somayajulu int i;
99611e25f0dSDavid C Somayajulu
99711e25f0dSDavid C Somayajulu if ((ha = (qlnx_host_t *)dev->si_drv1) == NULL)
99811e25f0dSDavid C Somayajulu return ENXIO;
99911e25f0dSDavid C Somayajulu
100011e25f0dSDavid C Somayajulu switch (cmd) {
100111e25f0dSDavid C Somayajulu case QLNX_GRC_DUMP_SIZE:
100211e25f0dSDavid C Somayajulu qlnx_get_grc_dump_size(ha, (qlnx_grcdump_t *)data);
100311e25f0dSDavid C Somayajulu break;
100411e25f0dSDavid C Somayajulu
100511e25f0dSDavid C Somayajulu case QLNX_GRC_DUMP:
100611e25f0dSDavid C Somayajulu rval = qlnx_get_grc_dump(ha, (qlnx_grcdump_t *)data);
100711e25f0dSDavid C Somayajulu break;
100811e25f0dSDavid C Somayajulu
100911e25f0dSDavid C Somayajulu case QLNX_IDLE_CHK_SIZE:
101011e25f0dSDavid C Somayajulu qlnx_get_idle_chk_size(ha, (qlnx_idle_chk_t *)data);
101111e25f0dSDavid C Somayajulu break;
101211e25f0dSDavid C Somayajulu
101311e25f0dSDavid C Somayajulu case QLNX_IDLE_CHK:
101411e25f0dSDavid C Somayajulu rval = qlnx_get_idle_chk(ha, (qlnx_idle_chk_t *)data);
101511e25f0dSDavid C Somayajulu break;
101611e25f0dSDavid C Somayajulu
101711e25f0dSDavid C Somayajulu case QLNX_DRV_INFO:
101811e25f0dSDavid C Somayajulu rval = qlnx_drv_info(ha, (qlnx_drvinfo_t *)data);
101911e25f0dSDavid C Somayajulu break;
102011e25f0dSDavid C Somayajulu
102111e25f0dSDavid C Somayajulu case QLNX_DEV_SETTING:
102211e25f0dSDavid C Somayajulu rval = qlnx_dev_settings(ha, (qlnx_dev_setting_t *)data);
102311e25f0dSDavid C Somayajulu break;
102411e25f0dSDavid C Somayajulu
102511e25f0dSDavid C Somayajulu case QLNX_GET_REGS:
102611e25f0dSDavid C Somayajulu rval = qlnx_get_regs(ha, (qlnx_get_regs_t *)data);
102711e25f0dSDavid C Somayajulu break;
102811e25f0dSDavid C Somayajulu
102911e25f0dSDavid C Somayajulu case QLNX_NVRAM:
103011e25f0dSDavid C Somayajulu rval = qlnx_nvram(ha, (qlnx_nvram_t *)data);
103111e25f0dSDavid C Somayajulu break;
103211e25f0dSDavid C Somayajulu
103311e25f0dSDavid C Somayajulu case QLNX_RD_WR_REG:
103411e25f0dSDavid C Somayajulu rval = qlnx_reg_rd_wr(ha, (qlnx_reg_rd_wr_t *)data);
103511e25f0dSDavid C Somayajulu break;
103611e25f0dSDavid C Somayajulu
103711e25f0dSDavid C Somayajulu case QLNX_RD_WR_PCICFG:
103811e25f0dSDavid C Somayajulu rval = qlnx_rd_wr_pci_config(ha, (qlnx_pcicfg_rd_wr_t *)data);
103911e25f0dSDavid C Somayajulu break;
104011e25f0dSDavid C Somayajulu
104111e25f0dSDavid C Somayajulu case QLNX_MAC_ADDR:
104211e25f0dSDavid C Somayajulu qlnx_mac_addr(ha, (qlnx_perm_mac_addr_t *)data);
104311e25f0dSDavid C Somayajulu break;
104411e25f0dSDavid C Somayajulu
104511e25f0dSDavid C Somayajulu case QLNX_STORM_STATS:
104611e25f0dSDavid C Somayajulu qlnx_storm_stats(ha, (qlnx_storm_stats_dump_t *)data);
104711e25f0dSDavid C Somayajulu break;
104811e25f0dSDavid C Somayajulu
104911e25f0dSDavid C Somayajulu case QLNX_TRACE_SIZE:
105011e25f0dSDavid C Somayajulu qlnx_get_trace_size(ha, (qlnx_trace_t *)data);
105111e25f0dSDavid C Somayajulu break;
105211e25f0dSDavid C Somayajulu
105311e25f0dSDavid C Somayajulu case QLNX_TRACE:
105411e25f0dSDavid C Somayajulu trace = (qlnx_trace_t *)data;
105511e25f0dSDavid C Somayajulu
105611e25f0dSDavid C Somayajulu for (i = 0; i < ha->cdev.num_hwfns; i++) {
105711e25f0dSDavid C Somayajulu if (trace->size[i] && trace->cmd && trace->buffer[i])
105811e25f0dSDavid C Somayajulu rval = qlnx_get_trace(ha, i, trace);
105911e25f0dSDavid C Somayajulu
106011e25f0dSDavid C Somayajulu if (rval)
106111e25f0dSDavid C Somayajulu break;
106211e25f0dSDavid C Somayajulu }
106311e25f0dSDavid C Somayajulu break;
106411e25f0dSDavid C Somayajulu
1065217ec208SDavid C Somayajulu #ifdef QLNX_USER_LLDP
1066217ec208SDavid C Somayajulu case QLNX_SET_LLDP_TLVS:
1067217ec208SDavid C Somayajulu rval = qlnx_set_lldp_tlvx(ha, (qlnx_lldp_sys_tlvs_t *)data);
1068217ec208SDavid C Somayajulu break;
1069217ec208SDavid C Somayajulu #endif /* #ifdef QLNX_USER_LLDP */
1070217ec208SDavid C Somayajulu
107111e25f0dSDavid C Somayajulu default:
107211e25f0dSDavid C Somayajulu rval = EINVAL;
107311e25f0dSDavid C Somayajulu break;
107411e25f0dSDavid C Somayajulu }
107511e25f0dSDavid C Somayajulu
107611e25f0dSDavid C Somayajulu return (rval);
107711e25f0dSDavid C Somayajulu }
1078