From 804e746c7b73385092b0bcfde1d1ff74e03f25f3 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Wed, 15 Jun 2016 14:23:02 -0700 Subject: [PATCH] net/bnxt: add hardware resource manager init code Start adding support to use the HWRM API. Hardware Resource Manager or HWRM in short, is a set of API provided by the firmware running in the ASIC to manage the various resources. Initial commit just performs necessary HWRM queries for init, then fails as before. Now that struct bnxt is non-zero size, we can set dev_private_size correctly. The used HWRM calls so far: bnxt_hwrm_func_qcaps: This command returns capabilities of a function. bnxt_hwrm_ver_get: This function is called by a driver to determine the HWRM interface version supported by the HWRM firmware, the version of HWRM firmware implementation, the name of HWRM firmware, the versions of other embedded firmwares, and the names of other embedded firmwares, etc. Gets the firmware version and interface specifications. Returns an error if the firmware on the device is not supported by the driver and ensures the response space is large enough for the largest possible response. bnxt_hwrm_queue_qportcfg: This function is called by a driver to query queue configuration of a port. Signed-off-by: Ajit Khaparde Signed-off-by: Stephen Hurd Reviewed-by: David Christensen --- drivers/net/bnxt/Makefile | 1 + drivers/net/bnxt/bnxt.h | 114 +++ drivers/net/bnxt/bnxt_ethdev.c | 111 ++- drivers/net/bnxt/bnxt_hwrm.c | 324 +++++++++ drivers/net/bnxt/bnxt_hwrm.h | 53 ++ drivers/net/bnxt/hsi_struct_def_dpdk.h | 954 +++++++++++++++++++++++++ 6 files changed, 1555 insertions(+), 2 deletions(-) create mode 100644 drivers/net/bnxt/bnxt.h create mode 100644 drivers/net/bnxt/bnxt_hwrm.c create mode 100644 drivers/net/bnxt/bnxt_hwrm.h create mode 100644 drivers/net/bnxt/hsi_struct_def_dpdk.h diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile index f6333fdad9..9965597fa4 100644 --- a/drivers/net/bnxt/Makefile +++ b/drivers/net/bnxt/Makefile @@ -49,6 +49,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map # all source are stored in SRCS-y # SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.c +SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_hwrm.c # # Export include files diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h new file mode 100644 index 0000000000..8cb7f5b76e --- /dev/null +++ b/drivers/net/bnxt/bnxt.h @@ -0,0 +1,114 @@ +/*- + * BSD LICENSE + * + * Copyright(c) Broadcom Limited. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Broadcom Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _BNXT_H_ +#define _BNXT_H_ + +#include +#include + +#include +#include +#include +#include + +struct bnxt_vf_info { + uint16_t fw_fid; + uint8_t mac_addr[ETHER_ADDR_LEN]; + uint16_t max_rsscos_ctx; + uint16_t max_cp_rings; + uint16_t max_tx_rings; + uint16_t max_rx_rings; + uint16_t max_l2_ctx; + uint16_t max_vnics; + struct bnxt_pf_info *pf; +}; + +struct bnxt_pf_info { +#define BNXT_FIRST_PF_FID 1 +#define BNXT_MAX_VFS(bp) (bp->pf.max_vfs) +#define BNXT_FIRST_VF_FID 128 +#define BNXT_PF_RINGS_USED(bp) bnxt_get_num_queues(bp) +#define BNXT_PF_RINGS_AVAIL(bp) (bp->pf.max_cp_rings - BNXT_PF_RINGS_USED(bp)) + uint32_t fw_fid; + uint8_t port_id; + uint8_t mac_addr[ETHER_ADDR_LEN]; + uint16_t max_rsscos_ctx; + uint16_t max_cp_rings; + uint16_t max_tx_rings; + uint16_t max_rx_rings; + uint16_t max_l2_ctx; + uint16_t max_vnics; + uint16_t first_vf_id; + uint16_t active_vfs; + uint16_t max_vfs; + void *vf_req_buf; + phys_addr_t vf_req_buf_dma_addr; + uint32_t vf_req_fwd[8]; + struct bnxt_vf_info *vf; +}; + +#define BNXT_COS_QUEUE_COUNT 8 +struct bnxt_cos_queue_info { + uint8_t id; + uint8_t profile; +}; + +struct bnxt { + void *bar0; + + struct rte_eth_dev *eth_dev; + struct rte_pci_device *pdev; + + uint32_t flags; +#define BNXT_FLAG_VF (1 << 1) +#define BNXT_PF(bp) (!((bp)->flags & BNXT_FLAG_VF)) +#define BNXT_VF(bp) ((bp)->flags & BNXT_FLAG_VF) + +#define MAX_NUM_MAC_ADDR 32 + uint8_t mac_addr[ETHER_ADDR_LEN]; + + uint16_t hwrm_cmd_seq; + void *hwrm_cmd_resp_addr; + phys_addr_t hwrm_cmd_resp_dma_addr; + rte_spinlock_t hwrm_lock; + uint16_t max_req_len; + uint16_t max_resp_len; + + struct bnxt_cos_queue_info cos_queue[BNXT_COS_QUEUE_COUNT]; + + struct bnxt_pf_info pf; + struct bnxt_vf_info vf; +}; + +#endif diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index af8a65fe4d..32ed0816e8 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -39,6 +39,9 @@ #include #include +#include "bnxt.h" +#include "bnxt_hwrm.h" + #define DRV_MODULE_NAME "bnxt" static const char bnxt_version[] = "Broadcom Cumulus driver " DRV_MODULE_NAME "\n"; @@ -49,14 +52,68 @@ static struct rte_pci_id bnxt_pci_id_map[] = { {.device_id = 0}, }; +static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev) +{ + struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; + + rte_free(eth_dev->data->mac_addrs); + bnxt_free_hwrm_resources(bp); +} + /* * Initialization */ +static struct eth_dev_ops bnxt_dev_ops = { + .dev_close = bnxt_dev_close_op, +}; + +static bool bnxt_vf_pciid(uint16_t id) +{ + if (id == BROADCOM_DEV_ID_57304_VF || + id == BROADCOM_DEV_ID_57406_VF) + return true; + return false; +} + +static int bnxt_init_board(struct rte_eth_dev *eth_dev) +{ + int rc; + struct bnxt *bp = eth_dev->data->dev_private; + + /* enable device (incl. PCI PM wakeup), and bus-mastering */ + if (!eth_dev->pci_dev->mem_resource[0].addr) { + RTE_LOG(ERR, PMD, + "Cannot find PCI device base address, aborting\n"); + rc = -ENODEV; + goto init_err_disable; + } + + bp->eth_dev = eth_dev; + bp->pdev = eth_dev->pci_dev; + + bp->bar0 = (void *)eth_dev->pci_dev->mem_resource[0].addr; + if (!bp->bar0) { + RTE_LOG(ERR, PMD, "Cannot map device registers, aborting\n"); + rc = -ENOMEM; + goto init_err_release; + } + return 0; + +init_err_release: + if (bp->bar0) + bp->bar0 = NULL; + +init_err_disable: + + return rc; +} + static int bnxt_dev_init(struct rte_eth_dev *eth_dev) { static int version_printed; + struct bnxt *bp; int rc; if (version_printed++ == 0) @@ -71,8 +128,58 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev) } rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev); - rc = -EPERM; + bp = eth_dev->data->dev_private; + + if (bnxt_vf_pciid(eth_dev->pci_dev->id.device_id)) + bp->flags |= BNXT_FLAG_VF; + + rc = bnxt_init_board(eth_dev); + if (rc) { + RTE_LOG(ERR, PMD, + "Board initialization failed rc: %x\n", rc); + goto error; + } + eth_dev->dev_ops = &bnxt_dev_ops; + /* eth_dev->rx_pkt_burst = &bnxt_recv_pkts; */ + /* eth_dev->tx_pkt_burst = &bnxt_xmit_pkts; */ + + rc = bnxt_alloc_hwrm_resources(bp); + if (rc) { + RTE_LOG(ERR, PMD, + "hwrm resource allocation failure rc: %x\n", rc); + goto error_free; + } + rc = bnxt_hwrm_ver_get(bp); + if (rc) + goto error_free; + bnxt_hwrm_queue_qportcfg(bp); + + /* Get the MAX capabilities for this function */ + rc = bnxt_hwrm_func_qcaps(bp); + if (rc) { + RTE_LOG(ERR, PMD, "hwrm query capability failure rc: %x\n", rc); + goto error_free; + } + eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl", + ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR, 0); + if (eth_dev->data->mac_addrs == NULL) { + RTE_LOG(ERR, PMD, + "Failed to alloc %u bytes needed to store MAC addr tbl", + ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR); + rc = -ENOMEM; + goto error_free; + } + /* Copy the permanent MAC from the qcap response address now. */ + if (BNXT_PF(bp)) + memcpy(bp->mac_addr, bp->pf.mac_addr, sizeof(bp->mac_addr)); + else + memcpy(bp->mac_addr, bp->vf.mac_addr, sizeof(bp->mac_addr)); + memcpy(ð_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN); + + return -EPERM; +error_free: + bnxt_dev_close_op(eth_dev); error: return rc; } @@ -90,7 +197,7 @@ static struct eth_driver bnxt_rte_pmd = { }, .eth_dev_init = bnxt_dev_init, .eth_dev_uninit = bnxt_dev_uninit, - .dev_private_size = 32 /* this must be non-zero apparently */, + .dev_private_size = sizeof(struct bnxt), }; static int bnxt_rte_pmd_init(const char *name, const char *params __rte_unused) diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c new file mode 100644 index 0000000000..e187121d74 --- /dev/null +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -0,0 +1,324 @@ +/*- + * BSD LICENSE + * + * Copyright(c) Broadcom Limited. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Broadcom Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "bnxt.h" +#include "bnxt_hwrm.h" +#include "hsi_struct_def_dpdk.h" + +#define HWRM_CMD_TIMEOUT 2000 + +/* + * HWRM Functions (sent to HWRM) + * These are named bnxt_hwrm_*() and return -1 if bnxt_hwrm_send_message() + * fails (ie: a timeout), and a positive non-zero HWRM error code if the HWRM + * command was failed by the ChiMP. + */ + +static int bnxt_hwrm_send_message_locked(struct bnxt *bp, void *msg, + uint32_t msg_len) +{ + unsigned int i; + struct input *req = msg; + struct output *resp = bp->hwrm_cmd_resp_addr; + uint32_t *data = msg; + uint8_t *bar; + uint8_t *valid; + + /* Write request msg to hwrm channel */ + for (i = 0; i < msg_len; i += 4) { + bar = (uint8_t *)bp->bar0 + i; + *(volatile uint32_t *)bar = *data; + data++; + } + + /* Zero the rest of the request space */ + for (; i < bp->max_req_len; i += 4) { + bar = (uint8_t *)bp->bar0 + i; + *(volatile uint32_t *)bar = 0; + } + + /* Ring channel doorbell */ + bar = (uint8_t *)bp->bar0 + 0x100; + *(volatile uint32_t *)bar = 1; + + /* Poll for the valid bit */ + for (i = 0; i < HWRM_CMD_TIMEOUT; i++) { + /* Sanity check on the resp->resp_len */ + rte_rmb(); + if (resp->resp_len && resp->resp_len <= + bp->max_resp_len) { + /* Last byte of resp contains the valid key */ + valid = (uint8_t *)resp + resp->resp_len - 1; + if (*valid == HWRM_RESP_VALID_KEY) + break; + } + rte_delay_us(600); + } + + if (i >= HWRM_CMD_TIMEOUT) { + RTE_LOG(ERR, PMD, "Error sending msg %x\n", + req->req_type); + goto err_ret; + } + return 0; + +err_ret: + return -1; +} + +static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len) +{ + int rc; + + rte_spinlock_lock(&bp->hwrm_lock); + rc = bnxt_hwrm_send_message_locked(bp, msg, msg_len); + rte_spinlock_unlock(&bp->hwrm_lock); + return rc; +} + +#define HWRM_PREP(req, type, cr, resp) \ + memset(bp->hwrm_cmd_resp_addr, 0, bp->max_resp_len); \ + req.req_type = rte_cpu_to_le_16(HWRM_##type); \ + req.cmpl_ring = rte_cpu_to_le_16(cr); \ + req.seq_id = rte_cpu_to_le_16(bp->hwrm_cmd_seq++); \ + req.target_id = rte_cpu_to_le_16(0xffff); \ + req.resp_addr = rte_cpu_to_le_64(bp->hwrm_cmd_resp_dma_addr) + +#define HWRM_CHECK_RESULT \ + { \ + if (rc) { \ + RTE_LOG(ERR, PMD, "%s failed rc:%d\n", \ + __func__, rc); \ + return rc; \ + } \ + if (resp->error_code) { \ + rc = rte_le_to_cpu_16(resp->error_code); \ + RTE_LOG(ERR, PMD, "%s error %d\n", __func__, rc); \ + return rc; \ + } \ + } + +int bnxt_hwrm_func_qcaps(struct bnxt *bp) +{ + int rc = 0; + struct hwrm_func_qcaps_input req = {.req_type = 0 }; + struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr; + + HWRM_PREP(req, FUNC_QCAPS, -1, resp); + + req.fid = rte_cpu_to_le_16(0xffff); + + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req)); + + HWRM_CHECK_RESULT; + + if (BNXT_PF(bp)) { + struct bnxt_pf_info *pf = &bp->pf; + + pf->fw_fid = rte_le_to_cpu_32(resp->fid); + pf->port_id = resp->port_id; + memcpy(pf->mac_addr, resp->perm_mac_address, ETHER_ADDR_LEN); + pf->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx); + pf->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings); + pf->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings); + pf->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings); + pf->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs); + pf->max_vnics = rte_le_to_cpu_16(resp->max_vnics); + pf->first_vf_id = rte_le_to_cpu_16(resp->first_vf_id); + pf->max_vfs = rte_le_to_cpu_16(resp->max_vfs); + } else { + struct bnxt_vf_info *vf = &bp->vf; + + vf->fw_fid = rte_le_to_cpu_32(resp->fid); + memcpy(vf->mac_addr, &resp->perm_mac_address, ETHER_ADDR_LEN); + vf->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx); + vf->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings); + vf->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings); + vf->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings); + vf->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs); + vf->max_vnics = rte_le_to_cpu_16(resp->max_vnics); + } + + return rc; +} + +int bnxt_hwrm_ver_get(struct bnxt *bp) +{ + int rc = 0; + struct hwrm_ver_get_input req = {.req_type = 0 }; + struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr; + uint32_t my_version; + uint32_t fw_version; + uint16_t max_resp_len; + char type[RTE_MEMZONE_NAMESIZE]; + + HWRM_PREP(req, VER_GET, -1, resp); + + req.hwrm_intf_maj = HWRM_VERSION_MAJOR; + req.hwrm_intf_min = HWRM_VERSION_MINOR; + req.hwrm_intf_upd = HWRM_VERSION_UPDATE; + + /* + * Hold the lock since we may be adjusting the response pointers. + */ + rte_spinlock_lock(&bp->hwrm_lock); + rc = bnxt_hwrm_send_message_locked(bp, &req, sizeof(req)); + + HWRM_CHECK_RESULT; + + RTE_LOG(INFO, PMD, "%d.%d.%d:%d.%d.%d\n", + resp->hwrm_intf_maj, resp->hwrm_intf_min, + resp->hwrm_intf_upd, + resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld); + + my_version = HWRM_VERSION_MAJOR << 16; + my_version |= HWRM_VERSION_MINOR << 8; + my_version |= HWRM_VERSION_UPDATE; + + fw_version = resp->hwrm_intf_maj << 16; + fw_version |= resp->hwrm_intf_min << 8; + fw_version |= resp->hwrm_intf_upd; + + if (resp->hwrm_intf_maj != HWRM_VERSION_MAJOR) { + RTE_LOG(ERR, PMD, "Unsupported firmware API version\n"); + rc = -EINVAL; + goto error; + } + + if (my_version != fw_version) { + RTE_LOG(INFO, PMD, "BNXT Driver/HWRM API mismatch.\n"); + if (my_version < fw_version) { + RTE_LOG(INFO, PMD, + "Firmware API version is newer than driver.\n"); + RTE_LOG(INFO, PMD, + "The driver may be missing features.\n"); + } else { + RTE_LOG(INFO, PMD, + "Firmware API version is older than driver.\n"); + RTE_LOG(INFO, PMD, + "Not all driver features may be functional.\n"); + } + } + + if (bp->max_req_len > resp->max_req_win_len) { + RTE_LOG(ERR, PMD, "Unsupported request length\n"); + rc = -EINVAL; + } + bp->max_req_len = resp->max_req_win_len; + max_resp_len = resp->max_resp_len; + if (bp->max_resp_len != max_resp_len) { + sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x", + bp->pdev->addr.domain, bp->pdev->addr.bus, + bp->pdev->addr.devid, bp->pdev->addr.function); + + rte_free(bp->hwrm_cmd_resp_addr); + + bp->hwrm_cmd_resp_addr = rte_malloc(type, max_resp_len, 0); + if (bp->hwrm_cmd_resp_addr == NULL) { + rc = -ENOMEM; + goto error; + } + bp->hwrm_cmd_resp_dma_addr = + rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr); + bp->max_resp_len = max_resp_len; + } + +error: + rte_spinlock_unlock(&bp->hwrm_lock); + return rc; +} + +int bnxt_hwrm_queue_qportcfg(struct bnxt *bp) +{ + int rc = 0; + struct hwrm_queue_qportcfg_input req = {.req_type = 0 }; + struct hwrm_queue_qportcfg_output *resp = bp->hwrm_cmd_resp_addr; + + HWRM_PREP(req, QUEUE_QPORTCFG, -1, resp); + + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req)); + + HWRM_CHECK_RESULT; + +#define GET_QUEUE_INFO(x) \ + bp->cos_queue[x].id = resp->queue_id##x; \ + bp->cos_queue[x].profile = resp->queue_id##x##_service_profile + + GET_QUEUE_INFO(0); + GET_QUEUE_INFO(1); + GET_QUEUE_INFO(2); + GET_QUEUE_INFO(3); + GET_QUEUE_INFO(4); + GET_QUEUE_INFO(5); + GET_QUEUE_INFO(6); + GET_QUEUE_INFO(7); + + return rc; +} + +/* + * HWRM utility functions + */ + +void bnxt_free_hwrm_resources(struct bnxt *bp) +{ + /* Release memzone */ + rte_free(bp->hwrm_cmd_resp_addr); + bp->hwrm_cmd_resp_addr = NULL; + bp->hwrm_cmd_resp_dma_addr = 0; +} + +int bnxt_alloc_hwrm_resources(struct bnxt *bp) +{ + struct rte_pci_device *pdev = bp->pdev; + char type[RTE_MEMZONE_NAMESIZE]; + + sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x", pdev->addr.domain, + pdev->addr.bus, pdev->addr.devid, pdev->addr.function); + bp->max_req_len = HWRM_MAX_REQ_LEN; + bp->max_resp_len = HWRM_MAX_RESP_LEN; + bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0); + if (bp->hwrm_cmd_resp_addr == NULL) + return -ENOMEM; + bp->hwrm_cmd_resp_dma_addr = + rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr); + rte_spinlock_init(&bp->hwrm_lock); + + return 0; +} diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h new file mode 100644 index 0000000000..e35e8c0fc8 --- /dev/null +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -0,0 +1,53 @@ +/*- + * BSD LICENSE + * + * Copyright(c) Broadcom Limited. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Broadcom Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _BNXT_HWRM_H_ +#define _BNXT_HWRM_H_ + +#include +#include + +#include "bnxt.h" + +#define HWRM_SEQ_ID_INVALID -1U + +int bnxt_hwrm_func_qcaps(struct bnxt *bp); + +int bnxt_hwrm_queue_qportcfg(struct bnxt *bp); + +int bnxt_hwrm_ver_get(struct bnxt *bp); + +void bnxt_free_hwrm_resources(struct bnxt *bp); +int bnxt_alloc_hwrm_resources(struct bnxt *bp); + +#endif diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h new file mode 100644 index 0000000000..c0bdbda4b9 --- /dev/null +++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h @@ -0,0 +1,954 @@ +/*- + * BSD LICENSE + * + * Copyright(c) Broadcom Limited. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Broadcom Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HSI_STRUCT_DEF_EXTERNAL_H_ +#define _HSI_STRUCT_DEF_EXTERNAL_H_ + +/* HW Resource Manager Specification 1.2.0 */ +#define HWRM_VERSION_MAJOR 1 +#define HWRM_VERSION_MINOR 2 +#define HWRM_VERSION_UPDATE 0 + +/* + * Following is the signature for HWRM message field that indicates not + * applicable (All F's). Need to cast it the size of the field if needed. + */ +#define HWRM_MAX_REQ_LEN (128) /* hwrm_func_buf_rgtr */ +#define HWRM_MAX_RESP_LEN (176) /* hwrm_func_qstats */ +#define HWRM_RESP_VALID_KEY 1 /* valid key for HWRM response */ + +/* + * Request types + */ +#define HWRM_VER_GET (UINT32_C(0x0)) +#define HWRM_FUNC_QCAPS (UINT32_C(0x15)) +#define HWRM_QUEUE_QPORTCFG (UINT32_C(0x30)) + +/* + * Note: The Hardware Resource Manager (HWRM) manages various hardware resources + * inside the chip. The HWRM is implemented in firmware, and runs on embedded + * processors inside the chip. This firmware is vital part of the chip's + * hardware. The chip can not be used by driver without it. + */ + +/* Input (16 bytes) */ +struct input { + /* + * This value indicates what type of request this is. The format for the + * rest of the command is determined by this field. + */ + uint16_t req_type; + + /* + * This value indicates the what completion ring the request will be + * optionally completed on. If the value is -1, then no CR completion + * will be generated. Any other value must be a valid CR ring_id value + * for this function. + */ + uint16_t cmpl_ring; + + /* This value indicates the command sequence number. */ + uint16_t seq_id; + + /* + * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids + * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM + */ + uint16_t target_id; + + /* + * This is the host address where the response will be written when the + * request is complete. This area must be 16B aligned and must be + * cleared to zero before the request is made. + */ + uint64_t resp_addr; +} __attribute__((packed)); + +/* Output (8 bytes) */ +struct output { + /* + * Pass/Fail or error type Note: receiver to verify the in parameters, + * and fail the call with an error when appropriate + */ + uint16_t error_code; + + /* This field returns the type of original request. */ + uint16_t req_type; + + /* This field provides original sequence number of the command. */ + uint16_t seq_id; + + /* + * This field is the length of the response in bytes. The last byte of + * the response is a valid flag that will read as '1' when the command + * has been completely written to memory. + */ + uint16_t resp_len; +} __attribute__((packed)); + +/* hwrm_func_qcaps */ +/* + * Description: This command returns capabilities of a function. The input FID + * value is used to indicate what function is being queried. This allows a + * physical function driver to query virtual functions that are children of the + * physical function. The output FID value is needed to configure Rings and + * MSI-X vectors so their DMA operations appear correctly on the PCI bus. + */ + +/* Input (24 bytes) */ +struct hwrm_func_qcaps_input { + /* + * This value indicates what type of request this is. The format for the + * rest of the command is determined by this field. + */ + uint16_t req_type; + + /* + * This value indicates the what completion ring the request will be + * optionally completed on. If the value is -1, then no CR completion + * will be generated. Any other value must be a valid CR ring_id value + * for this function. + */ + uint16_t cmpl_ring; + + /* This value indicates the command sequence number. */ + uint16_t seq_id; + + /* + * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids + * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM + */ + uint16_t target_id; + + /* + * This is the host address where the response will be written when the + * request is complete. This area must be 16B aligned and must be + * cleared to zero before the request is made. + */ + uint64_t resp_addr; + + /* + * Function ID of the function that is being queried. 0xFF... (All Fs) + * if the query is for the requesting function. + */ + uint16_t fid; + + uint16_t unused_0[3]; +} __attribute__((packed)); + +/* Output (80 bytes) */ +struct hwrm_func_qcaps_output { + /* + * Pass/Fail or error type Note: receiver to verify the in parameters, + * and fail the call with an error when appropriate + */ + uint16_t error_code; + + /* This field returns the type of original request. */ + uint16_t req_type; + + /* This field provides original sequence number of the command. */ + uint16_t seq_id; + + /* + * This field is the length of the response in bytes. The last byte of + * the response is a valid flag that will read as '1' when the command + * has been completely written to memory. + */ + uint16_t resp_len; + + /* + * FID value. This value is used to identify operations on the PCI bus + * as belonging to a particular PCI function. + */ + uint16_t fid; + + /* + * Port ID of port that this function is associated with. Valid only for + * the PF. 0xFF... (All Fs) if this function is not associated with any + * port. 0xFF... (All Fs) if this function is called from a VF. + */ + uint16_t port_id; + + /* If 1, then Push mode is supported on this function. */ + #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PUSH_MODE_SUPPORTED UINT32_C(0x1) + /* + * If 1, then the global MSI-X auto-masking is enabled for the device. + */ + #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_GLOBAL_MSIX_AUTOMASKING \ + UINT32_C(0x2) + /* + * If 1, then the Precision Time Protocol (PTP) processing is supported + * on this function. The HWRM should enable PTP on only a single + * Physical Function (PF) per port. + */ + #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED UINT32_C(0x4) + uint32_t flags; + + /* + * This value is current MAC address configured for this function. A + * value of 00-00-00-00-00-00 indicates no MAC address is currently + * configured. + */ + uint8_t perm_mac_address[6]; + + /* + * The maximum number of RSS/COS contexts that can be allocated to the + * function. + */ + uint16_t max_rsscos_ctx; + + /* + * The maximum number of completion rings that can be allocated to the + * function. + */ + uint16_t max_cmpl_rings; + + /* + * The maximum number of transmit rings that can be allocated to the + * function. + */ + uint16_t max_tx_rings; + + /* + * The maximum number of receive rings that can be allocated to the + * function. + */ + uint16_t max_rx_rings; + + /* + * The maximum number of L2 contexts that can be allocated to the + * function. + */ + uint16_t max_l2_ctxs; + + /* The maximum number of VNICs that can be allocated to the function. */ + uint16_t max_vnics; + + /* + * The identifier for the first VF enabled on a PF. This is valid only + * on the PF with SR-IOV enabled. 0xFF... (All Fs) if this command is + * called on a PF with SR-IOV disabled or on a VF. + */ + uint16_t first_vf_id; + + /* + * The maximum number of VFs that can be allocated to the function. This + * is valid only on the PF with SR-IOV enabled. 0xFF... (All Fs) if this + * command is called on a PF with SR-IOV disabled or on a VF. + */ + uint16_t max_vfs; + + /* + * The maximum number of statistic contexts that can be allocated to the + * function. + */ + uint16_t max_stat_ctx; + + /* + * The maximum number of Encapsulation records that can be offloaded by + * this function. + */ + uint32_t max_encap_records; + + /* + * The maximum number of decapsulation records that can be offloaded by + * this function. + */ + uint32_t max_decap_records; + + /* + * The maximum number of Exact Match (EM) flows that can be offloaded by + * this function on the TX side. + */ + uint32_t max_tx_em_flows; + + /* + * The maximum number of Wildcard Match (WM) flows that can be offloaded + * by this function on the TX side. + */ + uint32_t max_tx_wm_flows; + + /* + * The maximum number of Exact Match (EM) flows that can be offloaded by + * this function on the RX side. + */ + uint32_t max_rx_em_flows; + + /* + * The maximum number of Wildcard Match (WM) flows that can be offloaded + * by this function on the RX side. + */ + uint32_t max_rx_wm_flows; + + /* + * The maximum number of multicast filters that can be supported by this + * function on the RX side. + */ + uint32_t max_mcast_filters; + + /* + * The maximum value of flow_id that can be supported in completion + * records. + */ + uint32_t max_flow_id; + + /* + * The maximum number of HW ring groups that can be supported on this + * function. + */ + uint32_t max_hw_ring_grps; + + uint8_t unused_0; + uint8_t unused_1; + uint8_t unused_2; + + /* + * This field is used in Output records to indicate that the output is + * completely written to RAM. This field should be read as '1' to + * indicate that the output has been completely written. When writing a + * command completion or response to an internal processor, the order of + * writes has to be such that this field is written last. + */ + uint8_t valid; +} __attribute__((packed)); + +/* hwrm_ver_get */ +/* + * Description: This function is called by a driver to determine the HWRM + * interface version supported by the HWRM firmware, the version of HWRM + * firmware implementation, the name of HWRM firmware, the versions of other + * embedded firmwares, and the names of other embedded firmwares, etc. Any + * interface or firmware version with major = 0, minor = 0, and update = 0 shall + * be considered an invalid version. + */ + +/* Input (24 bytes) */ +struct hwrm_ver_get_input { + /* + * This value indicates what type of request this is. The format for the + * rest of the command is determined by this field. + */ + uint16_t req_type; + + /* + * This value indicates the what completion ring the request will be + * optionally completed on. If the value is -1, then no CR completion + * will be generated. Any other value must be a valid CR ring_id value + * for this function. + */ + uint16_t cmpl_ring; + + /* This value indicates the command sequence number. */ + uint16_t seq_id; + + /* + * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids + * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM + */ + uint16_t target_id; + + /* + * This is the host address where the response will be written when the + * request is complete. This area must be 16B aligned and must be + * cleared to zero before the request is made. + */ + uint64_t resp_addr; + + /* + * This field represents the major version of HWRM interface + * specification supported by the driver HWRM implementation. The + * interface major version is intended to change only when non backward + * compatible changes are made to the HWRM interface specification. + */ + uint8_t hwrm_intf_maj; + + /* + * This field represents the minor version of HWRM interface + * specification supported by the driver HWRM implementation. A change + * in interface minor version is used to reflect significant backward + * compatible modification to HWRM interface specification. This can be + * due to addition or removal of functionality. HWRM interface + * specifications with the same major version but different minor + * versions are compatible. + */ + uint8_t hwrm_intf_min; + + /* + * This field represents the update version of HWRM interface + * specification supported by the driver HWRM implementation. The + * interface update version is used to reflect minor changes or bug + * fixes to a released HWRM interface specification. + */ + uint8_t hwrm_intf_upd; + + uint8_t unused_0[5]; +} __attribute__((packed)); + +/* Output (128 bytes) */ +struct hwrm_ver_get_output { + /* + * Pass/Fail or error type Note: receiver to verify the in parameters, + * and fail the call with an error when appropriate + */ + uint16_t error_code; + + /* This field returns the type of original request. */ + uint16_t req_type; + + /* This field provides original sequence number of the command. */ + uint16_t seq_id; + + /* + * This field is the length of the response in bytes. The last byte of + * the response is a valid flag that will read as '1' when the command + * has been completely written to memory. + */ + uint16_t resp_len; + + /* + * This field represents the major version of HWRM interface + * specification supported by the HWRM implementation. The interface + * major version is intended to change only when non backward compatible + * changes are made to the HWRM interface specification. A HWRM + * implementation that is compliant with this specification shall + * provide value of 1 in this field. + */ + uint8_t hwrm_intf_maj; + + /* + * This field represents the minor version of HWRM interface + * specification supported by the HWRM implementation. A change in + * interface minor version is used to reflect significant backward + * compatible modification to HWRM interface specification. This can be + * due to addition or removal of functionality. HWRM interface + * specifications with the same major version but different minor + * versions are compatible. A HWRM implementation that is compliant with + * this specification shall provide value of 0 in this field. + */ + uint8_t hwrm_intf_min; + + /* + * This field represents the update version of HWRM interface + * specification supported by the HWRM implementation. The interface + * update version is used to reflect minor changes or bug fixes to a + * released HWRM interface specification. A HWRM implementation that is + * compliant with this specification shall provide value of 1 in this + * field. + */ + uint8_t hwrm_intf_upd; + + uint8_t hwrm_intf_rsvd; + + /* + * This field represents the major version of HWRM firmware. A change in + * firmware major version represents a major firmware release. + */ + uint8_t hwrm_fw_maj; + + /* + * This field represents the minor version of HWRM firmware. A change in + * firmware minor version represents significant firmware functionality + * changes. + */ + uint8_t hwrm_fw_min; + + /* + * This field represents the build version of HWRM firmware. A change in + * firmware build version represents bug fixes to a released firmware. + */ + uint8_t hwrm_fw_bld; + + /* + * This field is a reserved field. This field can be used to represent + * firmware branches or customer specific releases tied to a specific + * (major,minor,update) version of the HWRM firmware. + */ + uint8_t hwrm_fw_rsvd; + + /* + * This field represents the major version of mgmt firmware. A change in + * major version represents a major release. + */ + uint8_t mgmt_fw_maj; + + /* + * This field represents the minor version of mgmt firmware. A change in + * minor version represents significant functionality changes. + */ + uint8_t mgmt_fw_min; + + /* + * This field represents the build version of mgmt firmware. A change in + * update version represents bug fixes. + */ + uint8_t mgmt_fw_bld; + + /* + * This field is a reserved field. This field can be used to represent + * firmware branches or customer specific releases tied to a specific + * (major,minor,update) version + */ + uint8_t mgmt_fw_rsvd; + + /* + * This field represents the major version of network control firmware. + * A change in major version represents a major release. + */ + uint8_t netctrl_fw_maj; + + /* + * This field represents the minor version of network control firmware. + * A change in minor version represents significant functionality + * changes. + */ + uint8_t netctrl_fw_min; + + /* + * This field represents the build version of network control firmware. + * A change in update version represents bug fixes. + */ + uint8_t netctrl_fw_bld; + + /* + * This field is a reserved field. This field can be used to represent + * firmware branches or customer specific releases tied to a specific + * (major,minor,update) version + */ + uint8_t netctrl_fw_rsvd; + + /* + * This field is reserved for future use. The responder should set it to + * 0. The requester should ignore this field. + */ + uint32_t reserved1; + + /* + * This field represents the major version of RoCE firmware. A change in + * major version represents a major release. + */ + uint8_t roce_fw_maj; + + /* + * This field represents the minor version of RoCE firmware. A change in + * minor version represents significant functionality changes. + */ + uint8_t roce_fw_min; + + /* + * This field represents the build version of RoCE firmware. A change in + * update version represents bug fixes. + */ + uint8_t roce_fw_bld; + + /* + * This field is a reserved field. This field can be used to represent + * firmware branches or customer specific releases tied to a specific + * (major,minor,update) version + */ + uint8_t roce_fw_rsvd; + + /* + * This field represents the name of HWRM FW (ASCII chars without NULL + * at the end). + */ + char hwrm_fw_name[16]; + + /* + * This field represents the name of mgmt FW (ASCII chars without NULL + * at the end). + */ + char mgmt_fw_name[16]; + + /* + * This field represents the name of network control firmware (ASCII + * chars without NULL at the end). + */ + char netctrl_fw_name[16]; + + /* + * This field is reserved for future use. The responder should set it to + * 0. The requester should ignore this field. + */ + uint32_t reserved2[4]; + + /* + * This field represents the name of RoCE FW (ASCII chars without NULL + * at the end). + */ + char roce_fw_name[16]; + + /* This field returns the chip number. */ + uint16_t chip_num; + + /* This field returns the revision of chip. */ + uint8_t chip_rev; + + /* This field returns the chip metal number. */ + uint8_t chip_metal; + + /* This field returns the bond id of the chip. */ + uint8_t chip_bond_id; + + /* + * This value indicates the type of platform used for chip + * implementation. + */ + /* ASIC */ + #define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_ASIC \ + (UINT32_C(0x0) << 0) + /* FPGA platform of the chip. */ + #define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_FPGA \ + (UINT32_C(0x1) << 0) + /* Palladium platform of the chip. */ + #define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM \ + (UINT32_C(0x2) << 0) + uint8_t chip_platform_type; + + /* + * This field returns the maximum value of request window that is + * supported by the HWRM. The request window is mapped into device + * address space using MMIO. + */ + uint16_t max_req_win_len; + + /* + * This field returns the maximum value of response buffer in bytes. If + * a request specifies the response buffer length that is greater than + * this value, then the HWRM should fail it. The value of this field + * shall be 4KB or more. + */ + uint16_t max_resp_len; + + /* + * This field returns the default request timeout value in milliseconds. + */ + uint16_t def_req_timeout; + + uint8_t unused_0; + uint8_t unused_1; + uint8_t unused_2; + + /* + * This field is used in Output records to indicate that the output is + * completely written to RAM. This field should be read as '1' to + * indicate that the output has been completely written. When writing a + * command completion or response to an internal processor, the order of + * writes has to be such that this field is written last. + */ + uint8_t valid; +} __attribute__((packed)); + +/* hwrm_queue_qportcfg */ +/* + * Description: This function is called by a driver to query queue configuration + * of a port. # The HWRM shall at least advertise one queue with lossy service + * profile. # The driver shall use this command to query queue ids before + * configuring or using any queues. # If a service profile is not set for a + * queue, then the driver shall not use that queue without configuring a service + * profile for it. # If the driver is not allowed to configure service profiles, + * then the driver shall only use queues for which service profiles are pre- + * configured. + */ + +/* Input (24 bytes) */ +struct hwrm_queue_qportcfg_input { + /* + * This value indicates what type of request this is. The format for the + * rest of the command is determined by this field. + */ + uint16_t req_type; + + /* + * This value indicates the what completion ring the request will be + * optionally completed on. If the value is -1, then no CR completion + * will be generated. Any other value must be a valid CR ring_id value + * for this function. + */ + uint16_t cmpl_ring; + + /* This value indicates the command sequence number. */ + uint16_t seq_id; + + /* + * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids + * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM + */ + uint16_t target_id; + + /* + * This is the host address where the response will be written when the + * request is complete. This area must be 16B aligned and must be + * cleared to zero before the request is made. + */ + uint64_t resp_addr; + + /* + * Enumeration denoting the RX, TX type of the resource. This + * enumeration is used for resources that are similar for both TX and RX + * paths of the chip. + */ + #define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH \ + UINT32_C(0x1) + /* tx path */ + #define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX \ + (UINT32_C(0x0) << 0) + /* rx path */ + #define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX \ + (UINT32_C(0x1) << 0) + #define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST \ + HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX + uint32_t flags; + + /* + * Port ID of port for which the queue configuration is being queried. + * This field is only required when sent by IPC. + */ + uint16_t port_id; + + uint16_t unused_0; +} __attribute__((packed)); + +/* Output (32 bytes) */ +struct hwrm_queue_qportcfg_output { + /* + * Pass/Fail or error type Note: receiver to verify the in parameters, + * and fail the call with an error when appropriate + */ + uint16_t error_code; + + /* This field returns the type of original request. */ + uint16_t req_type; + + /* This field provides original sequence number of the command. */ + uint16_t seq_id; + + /* + * This field is the length of the response in bytes. The last byte of + * the response is a valid flag that will read as '1' when the command + * has been completely written to memory. + */ + uint16_t resp_len; + + /* The maximum number of queues that can be configured. */ + uint8_t max_configurable_queues; + + /* The maximum number of lossless queues that can be configured. */ + uint8_t max_configurable_lossless_queues; + + /* + * 0 - Not allowed. Non-zero - Allowed. If this value is non-zero, then + * the HWRM shall allow the host SW driver to configure queues using + * hwrm_queue_cfg. + */ + uint8_t queue_cfg_allowed; + + /* + * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then + * the HWRM shall allow the host SW driver to configure queue buffers + * using hwrm_queue_buffers_cfg. + */ + uint8_t queue_buffers_cfg_allowed; + + /* + * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then + * the HWRM shall allow the host SW driver to configure PFC using + * hwrm_queue_pfcenable_cfg. + */ + uint8_t queue_pfcenable_cfg_allowed; + + /* + * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then + * the HWRM shall allow the host SW driver to configure Priority to CoS + * mapping using hwrm_queue_pri2cos_cfg. + */ + uint8_t queue_pri2cos_cfg_allowed; + + /* + * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then + * the HWRM shall allow the host SW driver to configure CoS Bandwidth + * configuration using hwrm_queue_cos2bw_cfg. + */ + uint8_t queue_cos2bw_cfg_allowed; + + /* ID of CoS Queue 0. FF - Invalid id */ + uint8_t queue_id0; + + /* This value is applicable to CoS queues only. */ + /* Lossy (best-effort) */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \ + (UINT32_C(0x0) << 0) + /* Lossless */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \ + (UINT32_C(0x1) << 0) + /* + * Set to 0xFF... (All Fs) if there is no service profile + * specified + */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_UNKNOWN \ + (UINT32_C(0xff) << 0) + uint8_t queue_id0_service_profile; + + /* ID of CoS Queue 1. FF - Invalid id */ + uint8_t queue_id1; + /* This value is applicable to CoS queues only. */ + /* Lossy (best-effort) */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \ + (UINT32_C(0x0) << 0) + /* Lossless */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \ + (UINT32_C(0x1) << 0) + /* + * Set to 0xFF... (All Fs) if there is no service profile + * specified + */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_UNKNOWN \ + (UINT32_C(0xff) << 0) + uint8_t queue_id1_service_profile; + + /* ID of CoS Queue 2. FF - Invalid id */ + uint8_t queue_id2; + /* This value is applicable to CoS queues only. */ + /* Lossy (best-effort) */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \ + (UINT32_C(0x0) << 0) + /* Lossless */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \ + (UINT32_C(0x1) << 0) + /* + * Set to 0xFF... (All Fs) if there is no service profile + * specified + */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_UNKNOWN \ + (UINT32_C(0xff) << 0) + uint8_t queue_id2_service_profile; + + /* ID of CoS Queue 3. FF - Invalid id */ + uint8_t queue_id3; + + /* This value is applicable to CoS queues only. */ + /* Lossy (best-effort) */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \ + (UINT32_C(0x0) << 0) + /* Lossless */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \ + (UINT32_C(0x1) << 0) + /* + * Set to 0xFF... (All Fs) if there is no service profile + * specified + */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_UNKNOWN \ + (UINT32_C(0xff) << 0) + uint8_t queue_id3_service_profile; + + /* ID of CoS Queue 4. FF - Invalid id */ + uint8_t queue_id4; + /* This value is applicable to CoS queues only. */ + /* Lossy (best-effort) */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \ + (UINT32_C(0x0) << 0) + /* Lossless */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \ + (UINT32_C(0x1) << 0) + /* + * Set to 0xFF... (All Fs) if there is no service profile + * specified + */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_UNKNOWN \ + (UINT32_C(0xff) << 0) + uint8_t queue_id4_service_profile; + + /* ID of CoS Queue 5. FF - Invalid id */ + uint8_t queue_id5; + + /* This value is applicable to CoS queues only. */ + /* Lossy (best-effort) */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \ + (UINT32_C(0x0) << 0) + /* Lossless */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \ + (UINT32_C(0x1) << 0) + /* + * Set to 0xFF... (All Fs) if there is no service profile + * specified + */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \ + (UINT32_C(0xff) << 0) + uint8_t queue_id5_service_profile; + + /* ID of CoS Queue 6. FF - Invalid id */ + uint8_t queue_id6_service_profile; + /* This value is applicable to CoS queues only. */ + /* Lossy (best-effort) */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSY \ + (UINT32_C(0x0) << 0) + /* Lossless */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \ + (UINT32_C(0x1) << 0) + /* + * Set to 0xFF... (All Fs) if there is no service profile + * specified + */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \ + (UINT32_C(0xff) << 0) + uint8_t queue_id6; + + /* ID of CoS Queue 7. FF - Invalid id */ + uint8_t queue_id7; + + /* This value is applicable to CoS queues only. */ + /* Lossy (best-effort) */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \ + (UINT32_C(0x0) << 0) + /* Lossless */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \ + (UINT32_C(0x1) << 0) + /* + * Set to 0xFF... (All Fs) if there is no service profile + * specified + */ + #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \ + (UINT32_C(0xff) << 0) + uint8_t queue_id7_service_profile; + + /* + * This field is used in Output records to indicate that the output is + * completely written to RAM. This field should be read as '1' to + * indicate that the output has been completely written. When writing a + * command completion or response to an internal processor, the order of + * writes has to be such that this field is written last. + */ + uint8_t valid; +} __attribute__((packed)); + +#endif -- 2.20.1