--- /dev/null
+/*-
+ * 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 <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+
+#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;
+}
--- /dev/null
+/*-
+ * 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