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