summaryrefslogtreecommitdiffstats
path: root/src/spdk/dpdk/drivers/net/bnxt
diff options
context:
space:
mode:
Diffstat (limited to 'src/spdk/dpdk/drivers/net/bnxt')
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/Makefile51
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt.h352
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_cpr.c162
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_cpr.h92
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_ethdev.c3552
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_filter.c195
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_filter.h137
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_flow.c1171
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_hwrm.c3947
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_hwrm.h177
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_irq.c127
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_irq.h26
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_nvm_defs.h70
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_ring.c501
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_ring.h76
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_rxq.c471
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_rxq.h61
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_rxr.c805
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_rxr.h113
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_stats.c406
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_stats.h31
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_txq.c144
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_txq.h47
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_txr.c442
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_txr.h77
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_util.c18
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_util.h11
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_vnic.c240
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/bnxt_vnic.h65
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/hsi_struct_def_dpdk.h28211
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/meson.build20
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt.c811
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt.h326
-rw-r--r--src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt_version.map22
34 files changed, 42957 insertions, 0 deletions
diff --git a/src/spdk/dpdk/drivers/net/bnxt/Makefile b/src/spdk/dpdk/drivers/net/bnxt/Makefile
new file mode 100644
index 00000000..8be3cb0e
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/Makefile
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2014 Intel Corporation.
+# Copyright(c) 2014 6WIND S.A.
+# Copyright(c) Broadcom Limited.
+# All rights reserved.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_bnxt.a
+
+EXPORT_MAP := rte_pmd_bnxt_version.map
+
+LIBABIVER := 2
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
+LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
+
+EXPORT_MAP := rte_pmd_bnxt_version.map
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_cpr.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_flow.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_hwrm.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ring.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_rxq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_rxr.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txr.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_irq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_util.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += rte_pmd_bnxt.c
+
+#
+# Export include files
+#
+SYMLINK-y-include +=
+SYMLINK-$(CONFIG_RTE_LIBRTE_BNXT_PMD)-include := rte_pmd_bnxt.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt.h
new file mode 100644
index 00000000..db5c4eb0
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt.h
@@ -0,0 +1,352 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_H_
+#define _BNXT_H_
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <sys/queue.h>
+
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_ethdev_driver.h>
+#include <rte_memory.h>
+#include <rte_lcore.h>
+#include <rte_spinlock.h>
+#include <rte_time.h>
+
+#include "bnxt_cpr.h"
+
+#define BNXT_MAX_MTU 9500
+#define VLAN_TAG_SIZE 4
+#define BNXT_VF_RSV_NUM_RSS_CTX 1
+#define BNXT_VF_RSV_NUM_L2_CTX 4
+/* TODO: For now, do not support VMDq/RFS on VFs. */
+#define BNXT_VF_RSV_NUM_VNIC 1
+#define BNXT_MAX_LED 4
+#define BNXT_NUM_VLANS 2
+#define BNXT_MIN_RING_DESC 16
+#define BNXT_MAX_TX_RING_DESC 4096
+#define BNXT_MAX_RX_RING_DESC 8192
+#define BNXT_DB_SIZE 0x80
+
+#define BNXT_INT_LAT_TMR_MIN 75
+#define BNXT_INT_LAT_TMR_MAX 150
+#define BNXT_NUM_CMPL_AGGR_INT 36
+#define BNXT_CMPL_AGGR_DMA_TMR 37
+#define BNXT_NUM_CMPL_DMA_AGGR 36
+#define BNXT_CMPL_AGGR_DMA_TMR_DURING_INT 50
+#define BNXT_NUM_CMPL_DMA_AGGR_DURING_INT 12
+
+struct bnxt_led_info {
+ uint8_t led_id;
+ uint8_t led_type;
+ uint8_t led_group_id;
+ uint8_t unused;
+ uint16_t led_state_caps;
+#define BNXT_LED_ALT_BLINK_CAP(x) ((x) & \
+ rte_cpu_to_le_16(HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINKALT))
+
+ uint16_t led_color_caps;
+};
+
+struct bnxt_led_cfg {
+ uint8_t led_id;
+ uint8_t led_state;
+ uint8_t led_color;
+ uint8_t unused;
+ uint16_t led_blink_on;
+ uint16_t led_blink_off;
+ uint8_t led_group_id;
+ uint8_t rsvd;
+};
+
+#define BNXT_LED_DFLT_ENA \
+ (HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_ID | \
+ HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_STATE | \
+ HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_ON | \
+ HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_OFF | \
+ HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_GROUP_ID)
+
+#define BNXT_LED_DFLT_ENA_SHIFT 6
+
+#define BNXT_LED_DFLT_ENABLES(x) \
+ rte_cpu_to_le_32(BNXT_LED_DFLT_ENA << (BNXT_LED_DFLT_ENA_SHIFT * (x)))
+
+enum bnxt_hw_context {
+ HW_CONTEXT_NONE = 0,
+ HW_CONTEXT_IS_RSS = 1,
+ HW_CONTEXT_IS_COS = 2,
+ HW_CONTEXT_IS_LB = 3,
+};
+
+struct bnxt_vlan_table_entry {
+ uint16_t tpid;
+ uint16_t vid;
+} __attribute__((packed));
+
+struct bnxt_vlan_antispoof_table_entry {
+ uint16_t tpid;
+ uint16_t vid;
+ uint16_t mask;
+} __attribute__((packed));
+
+struct bnxt_child_vf_info {
+ void *req_buf;
+ struct bnxt_vlan_table_entry *vlan_table;
+ struct bnxt_vlan_antispoof_table_entry *vlan_as_table;
+ STAILQ_HEAD(, bnxt_filter_info) filter;
+ uint32_t func_cfg_flags;
+ uint32_t l2_rx_mask;
+ uint16_t fid;
+ uint16_t max_tx_rate;
+ uint16_t dflt_vlan;
+ uint16_t vlan_count;
+ uint8_t mac_spoof_en;
+ uint8_t vlan_spoof_en;
+ bool random_mac;
+ bool persist_stats;
+};
+
+struct bnxt_pf_info {
+#define BNXT_FIRST_PF_FID 1
+#define BNXT_MAX_VFS(bp) (bp->pf.max_vfs)
+#define BNXT_TOTAL_VFS(bp) ((bp)->pf.total_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))
+ uint16_t port_id;
+ uint16_t first_vf_id;
+ uint16_t active_vfs;
+ uint16_t max_vfs;
+ uint16_t total_vfs; /* Total VFs possible.
+ * Not necessarily enabled.
+ */
+ uint32_t func_cfg_flags;
+ void *vf_req_buf;
+ rte_iova_t vf_req_buf_dma_addr;
+ uint32_t vf_req_fwd[8];
+ uint16_t total_vnics;
+ struct bnxt_child_vf_info *vf_info;
+#define BNXT_EVB_MODE_NONE 0
+#define BNXT_EVB_MODE_VEB 1
+#define BNXT_EVB_MODE_VEPA 2
+ uint8_t evb_mode;
+};
+
+/* Max wait time is 10 * 100ms = 1s */
+#define BNXT_LINK_WAIT_CNT 10
+#define BNXT_LINK_WAIT_INTERVAL 100
+struct bnxt_link_info {
+ uint32_t phy_flags;
+ uint8_t mac_type;
+ uint8_t phy_link_status;
+ uint8_t loop_back;
+ uint8_t link_up;
+ uint8_t duplex;
+ uint8_t pause;
+ uint8_t force_pause;
+ uint8_t auto_pause;
+ uint8_t auto_mode;
+#define PHY_VER_LEN 3
+ uint8_t phy_ver[PHY_VER_LEN];
+ uint16_t link_speed;
+ uint16_t support_speeds;
+ uint16_t auto_link_speed;
+ uint16_t force_link_speed;
+ uint16_t auto_link_speed_mask;
+ uint32_t preemphasis;
+ uint8_t phy_type;
+ uint8_t media_type;
+};
+
+#define BNXT_COS_QUEUE_COUNT 8
+struct bnxt_cos_queue_info {
+ uint8_t id;
+ uint8_t profile;
+};
+
+struct rte_flow {
+ STAILQ_ENTRY(rte_flow) next;
+ struct bnxt_filter_info *filter;
+ struct bnxt_vnic_info *vnic;
+};
+
+struct bnxt_ptp_cfg {
+#define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400
+#define BNXT_GRCPF_REG_SYNC_TIME 0x480
+#define BNXT_CYCLECOUNTER_MASK 0xffffffffffffffffULL
+ struct rte_timecounter tc;
+ struct rte_timecounter tx_tstamp_tc;
+ struct rte_timecounter rx_tstamp_tc;
+ struct bnxt *bp;
+#define BNXT_MAX_TX_TS 1
+ uint16_t rxctl;
+#define BNXT_PTP_MSG_SYNC (1 << 0)
+#define BNXT_PTP_MSG_DELAY_REQ (1 << 1)
+#define BNXT_PTP_MSG_PDELAY_REQ (1 << 2)
+#define BNXT_PTP_MSG_PDELAY_RESP (1 << 3)
+#define BNXT_PTP_MSG_FOLLOW_UP (1 << 8)
+#define BNXT_PTP_MSG_DELAY_RESP (1 << 9)
+#define BNXT_PTP_MSG_PDELAY_RESP_FOLLOW_UP (1 << 10)
+#define BNXT_PTP_MSG_ANNOUNCE (1 << 11)
+#define BNXT_PTP_MSG_SIGNALING (1 << 12)
+#define BNXT_PTP_MSG_MANAGEMENT (1 << 13)
+#define BNXT_PTP_MSG_EVENTS (BNXT_PTP_MSG_SYNC | \
+ BNXT_PTP_MSG_DELAY_REQ | \
+ BNXT_PTP_MSG_PDELAY_REQ | \
+ BNXT_PTP_MSG_PDELAY_RESP)
+ uint8_t tx_tstamp_en:1;
+ int rx_filter;
+
+#define BNXT_PTP_RX_TS_L 0
+#define BNXT_PTP_RX_TS_H 1
+#define BNXT_PTP_RX_SEQ 2
+#define BNXT_PTP_RX_FIFO 3
+#define BNXT_PTP_RX_FIFO_PENDING 0x1
+#define BNXT_PTP_RX_FIFO_ADV 4
+#define BNXT_PTP_RX_REGS 5
+
+#define BNXT_PTP_TX_TS_L 0
+#define BNXT_PTP_TX_TS_H 1
+#define BNXT_PTP_TX_SEQ 2
+#define BNXT_PTP_TX_FIFO 3
+#define BNXT_PTP_TX_FIFO_EMPTY 0x2
+#define BNXT_PTP_TX_REGS 4
+ uint32_t rx_regs[BNXT_PTP_RX_REGS];
+ uint32_t rx_mapped_regs[BNXT_PTP_RX_REGS];
+ uint32_t tx_regs[BNXT_PTP_TX_REGS];
+ uint32_t tx_mapped_regs[BNXT_PTP_TX_REGS];
+};
+
+struct bnxt_coal {
+ uint16_t num_cmpl_aggr_int;
+ uint16_t num_cmpl_dma_aggr;
+ uint16_t num_cmpl_dma_aggr_during_int;
+ uint16_t int_lat_tmr_max;
+ uint16_t int_lat_tmr_min;
+ uint16_t cmpl_aggr_dma_tmr;
+ uint16_t cmpl_aggr_dma_tmr_during_int;
+};
+
+#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input)
+struct bnxt {
+ void *bar0;
+
+ struct rte_eth_dev *eth_dev;
+ struct rte_eth_rss_conf rss_conf;
+ struct rte_pci_device *pdev;
+ void *doorbell_base;
+
+ uint32_t flags;
+#define BNXT_FLAG_REGISTERED (1 << 0)
+#define BNXT_FLAG_VF (1 << 1)
+#define BNXT_FLAG_PORT_STATS (1 << 2)
+#define BNXT_FLAG_JUMBO (1 << 3)
+#define BNXT_FLAG_SHORT_CMD (1 << 4)
+#define BNXT_FLAG_UPDATE_HASH (1 << 5)
+#define BNXT_FLAG_PTP_SUPPORTED (1 << 6)
+#define BNXT_FLAG_MULTI_HOST (1 << 7)
+#define BNXT_FLAG_NEW_RM (1 << 30)
+#define BNXT_FLAG_INIT_DONE (1 << 31)
+#define BNXT_PF(bp) (!((bp)->flags & BNXT_FLAG_VF))
+#define BNXT_VF(bp) ((bp)->flags & BNXT_FLAG_VF)
+#define BNXT_NPAR(bp) ((bp)->port_partition_type)
+#define BNXT_MH(bp) ((bp)->flags & BNXT_FLAG_MULTI_HOST)
+#define BNXT_SINGLE_PF(bp) (BNXT_PF(bp) && !BNXT_NPAR(bp) && !BNXT_MH(bp))
+
+ unsigned int rx_nr_rings;
+ unsigned int rx_cp_nr_rings;
+ struct bnxt_rx_queue **rx_queues;
+ const void *rx_mem_zone;
+ struct rx_port_stats *hw_rx_port_stats;
+ rte_iova_t hw_rx_port_stats_map;
+
+ unsigned int tx_nr_rings;
+ unsigned int tx_cp_nr_rings;
+ struct bnxt_tx_queue **tx_queues;
+ const void *tx_mem_zone;
+ struct tx_port_stats *hw_tx_port_stats;
+ rte_iova_t hw_tx_port_stats_map;
+
+ /* Default completion ring */
+ struct bnxt_cp_ring_info *def_cp_ring;
+ uint32_t max_ring_grps;
+ struct bnxt_ring_grp_info *grp_info;
+
+ unsigned int nr_vnics;
+
+ struct bnxt_vnic_info *vnic_info;
+ STAILQ_HEAD(, bnxt_vnic_info) free_vnic_list;
+
+ struct bnxt_filter_info *filter_info;
+ STAILQ_HEAD(, bnxt_filter_info) free_filter_list;
+
+ /* VNIC pointer for flow filter (VMDq) pools */
+#define MAX_FF_POOLS 256
+ STAILQ_HEAD(, bnxt_vnic_info) ff_pool[MAX_FF_POOLS];
+
+ struct bnxt_irq *irq_tbl;
+
+#define MAX_NUM_MAC_ADDR 32
+ uint8_t mac_addr[ETHER_ADDR_LEN];
+
+ uint16_t hwrm_cmd_seq;
+ void *hwrm_cmd_resp_addr;
+ rte_iova_t hwrm_cmd_resp_dma_addr;
+ void *hwrm_short_cmd_req_addr;
+ rte_iova_t hwrm_short_cmd_req_dma_addr;
+ rte_spinlock_t hwrm_lock;
+ uint16_t max_req_len;
+ uint16_t max_resp_len;
+
+ struct bnxt_link_info link_info;
+ struct bnxt_cos_queue_info cos_queue[BNXT_COS_QUEUE_COUNT];
+ uint8_t tx_cosq_id;
+
+ uint16_t fw_fid;
+ uint8_t dflt_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 max_stat_ctx;
+ uint16_t vlan;
+ struct bnxt_pf_info pf;
+ uint8_t port_partition_type;
+ uint8_t dev_stopped;
+ uint8_t vxlan_port_cnt;
+ uint8_t geneve_port_cnt;
+ uint16_t vxlan_port;
+ uint16_t geneve_port;
+ uint16_t vxlan_fw_dst_port_id;
+ uint16_t geneve_fw_dst_port_id;
+ uint32_t fw_ver;
+ uint32_t hwrm_spec_code;
+
+ struct bnxt_led_info leds[BNXT_MAX_LED];
+ uint8_t num_leds;
+ struct bnxt_ptp_cfg *ptp_cfg;
+ uint16_t vf_resv_strategy;
+};
+
+int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
+
+bool is_bnxt_supported(struct rte_eth_dev *dev);
+bool bnxt_stratus_device(struct bnxt *bp);
+extern const struct rte_flow_ops bnxt_flow_ops;
+
+extern int bnxt_logtype_driver;
+#define PMD_DRV_LOG_RAW(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, bnxt_logtype_driver, "%s(): " fmt, \
+ __func__, ## args)
+
+#define PMD_DRV_LOG(level, fmt, args...) \
+ PMD_DRV_LOG_RAW(level, fmt, ## args)
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_cpr.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_cpr.c
new file mode 100644
index 00000000..ff20b6fd
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_cpr.c
@@ -0,0 +1,162 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_ring.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * Async event handling
+ */
+void bnxt_handle_async_event(struct bnxt *bp,
+ struct cmpl_base *cmp)
+{
+ struct hwrm_async_event_cmpl *async_cmp =
+ (struct hwrm_async_event_cmpl *)cmp;
+ uint16_t event_id = rte_le_to_cpu_16(async_cmp->event_id);
+
+ /* TODO: HWRM async events are not defined yet */
+ /* Needs to handle: link events, error events, etc. */
+ switch (event_id) {
+ case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
+ case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE:
+ case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE:
+ /* FALLTHROUGH */
+ bnxt_link_update_op(bp->eth_dev, 1);
+ break;
+ case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD:
+ PMD_DRV_LOG(INFO, "Async event: PF driver unloaded\n");
+ break;
+ case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE:
+ PMD_DRV_LOG(INFO, "Async event: VF config changed\n");
+ break;
+ case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED:
+ PMD_DRV_LOG(INFO, "Port conn async event\n");
+ break;
+ default:
+ PMD_DRV_LOG(INFO, "handle_async_event id = 0x%x\n", event_id);
+ break;
+ }
+}
+
+void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl)
+{
+ struct hwrm_exec_fwd_resp_input *fwreq;
+ struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
+ struct input *fwd_cmd;
+ uint16_t fw_vf_id;
+ uint16_t vf_id;
+ uint16_t req_len;
+ int rc;
+
+ if (bp->pf.active_vfs <= 0) {
+ PMD_DRV_LOG(ERR, "Forwarded VF with no active VFs\n");
+ return;
+ }
+
+ /* Qualify the fwd request */
+ fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
+ vf_id = fw_vf_id - bp->pf.first_vf_id;
+
+ req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) &
+ HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >>
+ HWRM_FWD_REQ_CMPL_REQ_LEN_SFT;
+ if (req_len > sizeof(fwreq->encap_request))
+ req_len = sizeof(fwreq->encap_request);
+
+ /* Locate VF's forwarded command */
+ fwd_cmd = (struct input *)bp->pf.vf_info[vf_id].req_buf;
+
+ if (fw_vf_id < bp->pf.first_vf_id ||
+ fw_vf_id >= (bp->pf.first_vf_id) + bp->pf.active_vfs) {
+ PMD_DRV_LOG(ERR,
+ "FWD req's source_id 0x%x out of range 0x%x - 0x%x (%d %d)\n",
+ fw_vf_id, bp->pf.first_vf_id,
+ (bp->pf.first_vf_id) + bp->pf.active_vfs - 1,
+ bp->pf.first_vf_id, bp->pf.active_vfs);
+ goto reject;
+ }
+
+ if (bnxt_rcv_msg_from_vf(bp, vf_id, fwd_cmd) == true) {
+ /*
+ * In older firmware versions, the MAC had to be all zeros for
+ * the VF to set it's MAC via hwrm_func_vf_cfg. Set to all
+ * zeros if it's being configured and has been ok'd by caller.
+ */
+ if (fwd_cmd->req_type == HWRM_FUNC_VF_CFG) {
+ struct hwrm_func_vf_cfg_input *vfc = (void *)fwd_cmd;
+
+ if (vfc->enables &
+ HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR) {
+ bnxt_hwrm_func_vf_mac(bp, vf_id,
+ (const uint8_t *)"\x00\x00\x00\x00\x00");
+ }
+ }
+ if (fwd_cmd->req_type == HWRM_CFA_L2_SET_RX_MASK) {
+ struct hwrm_cfa_l2_set_rx_mask_input *srm =
+ (void *)fwd_cmd;
+
+ srm->vlan_tag_tbl_addr = rte_cpu_to_le_64(0);
+ srm->num_vlan_tags = rte_cpu_to_le_32(0);
+ srm->mask &= ~rte_cpu_to_le_32(
+ HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY |
+ HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN |
+ HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN);
+ }
+ /* Forward */
+ rc = bnxt_hwrm_exec_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "Failed to send FWD req VF 0x%x, type 0x%x.\n",
+ fw_vf_id - bp->pf.first_vf_id,
+ rte_le_to_cpu_16(fwd_cmd->req_type));
+ }
+ return;
+ }
+
+reject:
+ rc = bnxt_hwrm_reject_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "Failed to send REJECT req VF 0x%x, type 0x%x.\n",
+ fw_vf_id - bp->pf.first_vf_id,
+ rte_le_to_cpu_16(fwd_cmd->req_type));
+ }
+
+ return;
+}
+
+int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp)
+{
+ bool evt = 0;
+
+ if (bp == NULL || cmp == NULL) {
+ PMD_DRV_LOG(ERR, "invalid NULL argument\n");
+ return evt;
+ }
+
+ switch (CMP_TYPE(cmp)) {
+ case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT:
+ /* Handle any async event */
+ bnxt_handle_async_event(bp, cmp);
+ evt = 1;
+ break;
+ case CMPL_BASE_TYPE_HWRM_FWD_RESP:
+ /* Handle HWRM forwarded responses */
+ bnxt_handle_fwd_req(bp, cmp);
+ evt = 1;
+ break;
+ default:
+ /* Ignore any other events */
+ PMD_DRV_LOG(INFO, "Ignoring %02x completion\n", CMP_TYPE(cmp));
+ break;
+ }
+
+ return evt;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_cpr.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_cpr.h
new file mode 100644
index 00000000..c7af5698
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_cpr.h
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_CPR_H_
+#define _BNXT_CPR_H_
+#include <stdbool.h>
+
+#include <rte_io.h>
+
+#define CMP_VALID(cmp, raw_cons, ring) \
+ (!!(((struct cmpl_base *)(cmp))->info3_v & CMPL_BASE_V) == \
+ !((raw_cons) & ((ring)->ring_size)))
+
+#define CMPL_VALID(cmp, v) \
+ (!!(((struct cmpl_base *)(cmp))->info3_v & CMPL_BASE_V) == !(v))
+
+#define CMP_TYPE(cmp) \
+ (((struct cmpl_base *)cmp)->type & CMPL_BASE_TYPE_MASK)
+
+#define ADV_RAW_CMP(idx, n) ((idx) + (n))
+#define NEXT_RAW_CMP(idx) ADV_RAW_CMP(idx, 1)
+#define RING_CMP(ring, idx) ((idx) & (ring)->ring_mask)
+#define RING_CMPL(ring_mask, idx) ((idx) & (ring_mask))
+#define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1))
+#define FLIP_VALID(cons, mask, val) ((cons) >= (mask) ? !(val) : (val))
+
+#define DB_CP_REARM_FLAGS (DB_KEY_CP | DB_IDX_VALID)
+#define DB_CP_FLAGS (DB_KEY_CP | DB_IDX_VALID | DB_IRQ_DIS)
+
+#define NEXT_CMPL(cpr, idx, v, inc) do { \
+ (idx) += (inc); \
+ if (unlikely((idx) == (cpr)->cp_ring_struct->ring_size)) { \
+ (v) = !(v); \
+ (idx) = 0; \
+ } \
+} while (0)
+#define B_CP_DB_REARM(cpr, raw_cons) \
+ rte_write32((DB_CP_REARM_FLAGS | \
+ RING_CMP(((cpr)->cp_ring_struct), raw_cons)), \
+ ((cpr)->cp_doorbell))
+
+#define B_CP_DB_ARM(cpr) rte_write32((DB_KEY_CP), ((cpr)->cp_doorbell))
+#define B_CP_DB_DISARM(cpr) (*(uint32_t *)((cpr)->cp_doorbell) = \
+ DB_KEY_CP | DB_IRQ_DIS)
+
+#define B_CP_DB_IDX_ARM(cpr, cons) \
+ (*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_REARM_FLAGS | \
+ (cons)))
+
+#define B_CP_DB_IDX_DISARM(cpr, cons) do { \
+ rte_smp_wmb(); \
+ (*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_FLAGS | \
+ (cons)); \
+} while (0)
+#define B_CP_DIS_DB(cpr, raw_cons) \
+ rte_write32((DB_CP_FLAGS | \
+ RING_CMP(((cpr)->cp_ring_struct), raw_cons)), \
+ ((cpr)->cp_doorbell))
+#define B_CP_DB(cpr, raw_cons, ring_mask) \
+ rte_write32((DB_CP_FLAGS | \
+ RING_CMPL((ring_mask), raw_cons)), \
+ ((cpr)->cp_doorbell))
+
+struct bnxt_ring;
+struct bnxt_cp_ring_info {
+ uint32_t cp_raw_cons;
+ void *cp_doorbell;
+
+ struct cmpl_base *cp_desc_ring;
+
+ rte_iova_t cp_desc_mapping;
+
+ struct ctx_hw_stats *hw_stats;
+ rte_iova_t hw_stats_map;
+ uint32_t hw_stats_ctx_id;
+
+ struct bnxt_ring *cp_ring_struct;
+ uint16_t cp_cons;
+ bool valid;
+};
+
+#define RX_CMP_L2_ERRORS \
+ (RX_PKT_CMPL_ERRORS_BUFFER_ERROR_MASK | RX_PKT_CMPL_ERRORS_CRC_ERROR)
+
+struct bnxt;
+void bnxt_handle_async_event(struct bnxt *bp, struct cmpl_base *cmp);
+void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmp);
+int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp);
+
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_ethdev.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_ethdev.c
new file mode 100644
index 00000000..cc7e4391
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_ethdev.c
@@ -0,0 +1,3552 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <rte_dev.h>
+#include <rte_ethdev_driver.h>
+#include <rte_ethdev_pci.h>
+#include <rte_malloc.h>
+#include <rte_cycles.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_irq.h"
+#include "bnxt_ring.h"
+#include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
+#include "bnxt_stats.h"
+#include "bnxt_txq.h"
+#include "bnxt_txr.h"
+#include "bnxt_vnic.h"
+#include "hsi_struct_def_dpdk.h"
+#include "bnxt_nvm_defs.h"
+#include "bnxt_util.h"
+
+#define DRV_MODULE_NAME "bnxt"
+static const char bnxt_version[] =
+ "Broadcom NetXtreme driver " DRV_MODULE_NAME "\n";
+int bnxt_logtype_driver;
+
+#define PCI_VENDOR_ID_BROADCOM 0x14E4
+
+#define BROADCOM_DEV_ID_STRATUS_NIC_VF1 0x1606
+#define BROADCOM_DEV_ID_STRATUS_NIC_VF2 0x1609
+#define BROADCOM_DEV_ID_STRATUS_NIC 0x1614
+#define BROADCOM_DEV_ID_57414_VF 0x16c1
+#define BROADCOM_DEV_ID_57301 0x16c8
+#define BROADCOM_DEV_ID_57302 0x16c9
+#define BROADCOM_DEV_ID_57304_PF 0x16ca
+#define BROADCOM_DEV_ID_57304_VF 0x16cb
+#define BROADCOM_DEV_ID_57417_MF 0x16cc
+#define BROADCOM_DEV_ID_NS2 0x16cd
+#define BROADCOM_DEV_ID_57311 0x16ce
+#define BROADCOM_DEV_ID_57312 0x16cf
+#define BROADCOM_DEV_ID_57402 0x16d0
+#define BROADCOM_DEV_ID_57404 0x16d1
+#define BROADCOM_DEV_ID_57406_PF 0x16d2
+#define BROADCOM_DEV_ID_57406_VF 0x16d3
+#define BROADCOM_DEV_ID_57402_MF 0x16d4
+#define BROADCOM_DEV_ID_57407_RJ45 0x16d5
+#define BROADCOM_DEV_ID_57412 0x16d6
+#define BROADCOM_DEV_ID_57414 0x16d7
+#define BROADCOM_DEV_ID_57416_RJ45 0x16d8
+#define BROADCOM_DEV_ID_57417_RJ45 0x16d9
+#define BROADCOM_DEV_ID_5741X_VF 0x16dc
+#define BROADCOM_DEV_ID_57412_MF 0x16de
+#define BROADCOM_DEV_ID_57314 0x16df
+#define BROADCOM_DEV_ID_57317_RJ45 0x16e0
+#define BROADCOM_DEV_ID_5731X_VF 0x16e1
+#define BROADCOM_DEV_ID_57417_SFP 0x16e2
+#define BROADCOM_DEV_ID_57416_SFP 0x16e3
+#define BROADCOM_DEV_ID_57317_SFP 0x16e4
+#define BROADCOM_DEV_ID_57404_MF 0x16e7
+#define BROADCOM_DEV_ID_57406_MF 0x16e8
+#define BROADCOM_DEV_ID_57407_SFP 0x16e9
+#define BROADCOM_DEV_ID_57407_MF 0x16ea
+#define BROADCOM_DEV_ID_57414_MF 0x16ec
+#define BROADCOM_DEV_ID_57416_MF 0x16ee
+#define BROADCOM_DEV_ID_58802 0xd802
+#define BROADCOM_DEV_ID_58804 0xd804
+#define BROADCOM_DEV_ID_58808 0x16f0
+#define BROADCOM_DEV_ID_58802_VF 0xd800
+
+static const struct rte_pci_id bnxt_pci_id_map[] = {
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM,
+ BROADCOM_DEV_ID_STRATUS_NIC_VF1) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM,
+ BROADCOM_DEV_ID_STRATUS_NIC_VF2) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_STRATUS_NIC) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_VF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57302) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_PF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_NS2) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_PF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402_MF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_RJ45) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404_MF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_MF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_SFP) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_MF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5741X_VF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5731X_VF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57314) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_MF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57311) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57312) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_RJ45) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_RJ45) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412_MF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_RJ45) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_SFP) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_SFP) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_SFP) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_MF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_MF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58802) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58804) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58808) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58802_VF) },
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+#define BNXT_ETH_RSS_SUPPORT ( \
+ ETH_RSS_IPV4 | \
+ ETH_RSS_NONFRAG_IPV4_TCP | \
+ ETH_RSS_NONFRAG_IPV4_UDP | \
+ ETH_RSS_IPV6 | \
+ ETH_RSS_NONFRAG_IPV6_TCP | \
+ ETH_RSS_NONFRAG_IPV6_UDP)
+
+#define BNXT_DEV_TX_OFFLOAD_SUPPORT (DEV_TX_OFFLOAD_VLAN_INSERT | \
+ DEV_TX_OFFLOAD_IPV4_CKSUM | \
+ DEV_TX_OFFLOAD_TCP_CKSUM | \
+ DEV_TX_OFFLOAD_UDP_CKSUM | \
+ DEV_TX_OFFLOAD_TCP_TSO | \
+ DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ DEV_TX_OFFLOAD_VXLAN_TNL_TSO | \
+ DEV_TX_OFFLOAD_GRE_TNL_TSO | \
+ DEV_TX_OFFLOAD_IPIP_TNL_TSO | \
+ DEV_TX_OFFLOAD_GENEVE_TNL_TSO | \
+ DEV_TX_OFFLOAD_MULTI_SEGS)
+
+#define BNXT_DEV_RX_OFFLOAD_SUPPORT (DEV_RX_OFFLOAD_VLAN_FILTER | \
+ DEV_RX_OFFLOAD_VLAN_STRIP | \
+ DEV_RX_OFFLOAD_IPV4_CKSUM | \
+ DEV_RX_OFFLOAD_UDP_CKSUM | \
+ DEV_RX_OFFLOAD_TCP_CKSUM | \
+ DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | \
+ DEV_RX_OFFLOAD_JUMBO_FRAME | \
+ DEV_RX_OFFLOAD_CRC_STRIP | \
+ DEV_RX_OFFLOAD_KEEP_CRC | \
+ DEV_RX_OFFLOAD_TCP_LRO)
+
+static int bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
+static void bnxt_print_link_info(struct rte_eth_dev *eth_dev);
+static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu);
+static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev);
+
+/***********************/
+
+/*
+ * High level utility functions
+ */
+
+static void bnxt_free_mem(struct bnxt *bp)
+{
+ bnxt_free_filter_mem(bp);
+ bnxt_free_vnic_attributes(bp);
+ bnxt_free_vnic_mem(bp);
+
+ bnxt_free_stats(bp);
+ bnxt_free_tx_rings(bp);
+ bnxt_free_rx_rings(bp);
+}
+
+static int bnxt_alloc_mem(struct bnxt *bp)
+{
+ int rc;
+
+ rc = bnxt_alloc_vnic_mem(bp);
+ if (rc)
+ goto alloc_mem_err;
+
+ rc = bnxt_alloc_vnic_attributes(bp);
+ if (rc)
+ goto alloc_mem_err;
+
+ rc = bnxt_alloc_filter_mem(bp);
+ if (rc)
+ goto alloc_mem_err;
+
+ return 0;
+
+alloc_mem_err:
+ bnxt_free_mem(bp);
+ return rc;
+}
+
+static int bnxt_init_chip(struct bnxt *bp)
+{
+ struct bnxt_rx_queue *rxq;
+ struct rte_eth_link new;
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+ uint32_t intr_vector = 0;
+ uint32_t queue_id, base = BNXT_MISC_VEC_ID;
+ uint32_t vec = BNXT_MISC_VEC_ID;
+ unsigned int i, j;
+ int rc;
+
+ /* disable uio/vfio intr/eventfd mapping */
+ rte_intr_disable(intr_handle);
+
+ if (bp->eth_dev->data->mtu > ETHER_MTU) {
+ bp->eth_dev->data->dev_conf.rxmode.offloads |=
+ DEV_RX_OFFLOAD_JUMBO_FRAME;
+ bp->flags |= BNXT_FLAG_JUMBO;
+ } else {
+ bp->eth_dev->data->dev_conf.rxmode.offloads &=
+ ~DEV_RX_OFFLOAD_JUMBO_FRAME;
+ bp->flags &= ~BNXT_FLAG_JUMBO;
+ }
+
+ rc = bnxt_alloc_all_hwrm_stat_ctxs(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "HWRM stat ctx alloc failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ rc = bnxt_alloc_hwrm_rings(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "HWRM ring alloc failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ rc = bnxt_alloc_all_hwrm_ring_grps(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "HWRM ring grp alloc failure: %x\n", rc);
+ goto err_out;
+ }
+
+ rc = bnxt_mq_rx_configure(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "MQ mode configure failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ /* VNIC configuration */
+ for (i = 0; i < bp->nr_vnics; i++) {
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+ uint32_t size = sizeof(*vnic->fw_grp_ids) * bp->max_ring_grps;
+
+ vnic->fw_grp_ids = rte_zmalloc("vnic_fw_grp_ids", size, 0);
+ if (!vnic->fw_grp_ids) {
+ PMD_DRV_LOG(ERR,
+ "Failed to alloc %d bytes for group ids\n",
+ size);
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ memset(vnic->fw_grp_ids, -1, size);
+
+ rc = bnxt_hwrm_vnic_alloc(bp, vnic);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "HWRM vnic %d alloc failure rc: %x\n",
+ i, rc);
+ goto err_out;
+ }
+
+ /* Alloc RSS context only if RSS mode is enabled */
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS) {
+ rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "HWRM vnic %d ctx alloc failure rc: %x\n",
+ i, rc);
+ goto err_out;
+ }
+ }
+
+ rc = bnxt_hwrm_vnic_cfg(bp, vnic);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "HWRM vnic %d cfg failure rc: %x\n",
+ i, rc);
+ goto err_out;
+ }
+
+ rc = bnxt_set_hwrm_vnic_filters(bp, vnic);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "HWRM vnic %d filter failure rc: %x\n",
+ i, rc);
+ goto err_out;
+ }
+
+ for (j = 0; j < bp->rx_nr_rings; j++) {
+ rxq = bp->eth_dev->data->rx_queues[j];
+
+ if (rxq->rx_deferred_start)
+ rxq->vnic->fw_grp_ids[j] = INVALID_HW_RING_ID;
+ }
+
+ rc = bnxt_vnic_rss_configure(bp, vnic);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "HWRM vnic set RSS failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+
+ if (bp->eth_dev->data->dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_TCP_LRO)
+ bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 1);
+ else
+ bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0);
+ }
+ rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "HWRM cfa l2 rx mask failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ /* check and configure queue intr-vector mapping */
+ if ((rte_intr_cap_multiple(intr_handle) ||
+ !RTE_ETH_DEV_SRIOV(bp->eth_dev).active) &&
+ bp->eth_dev->data->dev_conf.intr_conf.rxq != 0) {
+ intr_vector = bp->eth_dev->data->nb_rx_queues;
+ PMD_DRV_LOG(DEBUG, "intr_vector = %d\n", intr_vector);
+ if (intr_vector > bp->rx_cp_nr_rings) {
+ PMD_DRV_LOG(ERR, "At most %d intr queues supported",
+ bp->rx_cp_nr_rings);
+ return -ENOTSUP;
+ }
+ if (rte_intr_efd_enable(intr_handle, intr_vector))
+ return -1;
+ }
+
+ if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {
+ intr_handle->intr_vec =
+ rte_zmalloc("intr_vec",
+ bp->eth_dev->data->nb_rx_queues *
+ sizeof(int), 0);
+ if (intr_handle->intr_vec == NULL) {
+ PMD_DRV_LOG(ERR, "Failed to allocate %d rx_queues"
+ " intr_vec", bp->eth_dev->data->nb_rx_queues);
+ return -ENOMEM;
+ }
+ PMD_DRV_LOG(DEBUG, "intr_handle->intr_vec = %p "
+ "intr_handle->nb_efd = %d intr_handle->max_intr = %d\n",
+ intr_handle->intr_vec, intr_handle->nb_efd,
+ intr_handle->max_intr);
+ }
+
+ for (queue_id = 0; queue_id < bp->eth_dev->data->nb_rx_queues;
+ queue_id++) {
+ intr_handle->intr_vec[queue_id] = vec;
+ if (vec < base + intr_handle->nb_efd - 1)
+ vec++;
+ }
+
+ /* enable uio/vfio intr/eventfd mapping */
+ rte_intr_enable(intr_handle);
+
+ rc = bnxt_get_hwrm_link_config(bp, &new);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "HWRM Get link config failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ if (!bp->link_info.link_up) {
+ rc = bnxt_set_hwrm_link_config(bp, true);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "HWRM link config failure rc: %x\n", rc);
+ goto err_out;
+ }
+ }
+ bnxt_print_link_info(bp->eth_dev);
+
+ return 0;
+
+err_out:
+ bnxt_free_all_hwrm_resources(bp);
+
+ /* Some of the error status returned by FW may not be from errno.h */
+ if (rc > 0)
+ rc = -EIO;
+
+ return rc;
+}
+
+static int bnxt_shutdown_nic(struct bnxt *bp)
+{
+ bnxt_free_all_hwrm_resources(bp);
+ bnxt_free_all_filters(bp);
+ bnxt_free_all_vnics(bp);
+ return 0;
+}
+
+static int bnxt_init_nic(struct bnxt *bp)
+{
+ int rc;
+
+ rc = bnxt_init_ring_grps(bp);
+ if (rc)
+ return rc;
+
+ bnxt_init_vnics(bp);
+ bnxt_init_filters(bp);
+
+ return 0;
+}
+
+/*
+ * Device configuration and status function
+ */
+
+static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_dev_info *dev_info)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ uint16_t max_vnics, i, j, vpool, vrxq;
+ unsigned int max_rx_rings;
+
+ /* MAC Specifics */
+ dev_info->max_mac_addrs = bp->max_l2_ctx;
+ dev_info->max_hash_mac_addrs = 0;
+
+ /* PF/VF specifics */
+ if (BNXT_PF(bp))
+ dev_info->max_vfs = bp->pdev->max_vfs;
+ max_rx_rings = RTE_MIN(bp->max_vnics, bp->max_stat_ctx);
+ /* For the sake of symmetry, max_rx_queues = max_tx_queues */
+ dev_info->max_rx_queues = max_rx_rings;
+ dev_info->max_tx_queues = max_rx_rings;
+ dev_info->reta_size = HW_HASH_INDEX_SIZE;
+ dev_info->hash_key_size = 40;
+ max_vnics = bp->max_vnics;
+
+ /* Fast path specifics */
+ dev_info->min_rx_bufsize = 1;
+ dev_info->max_rx_pktlen = BNXT_MAX_MTU + ETHER_HDR_LEN + ETHER_CRC_LEN
+ + VLAN_TAG_SIZE;
+
+ dev_info->rx_offload_capa = BNXT_DEV_RX_OFFLOAD_SUPPORT;
+ if (bp->flags & BNXT_FLAG_PTP_SUPPORTED)
+ dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP;
+ dev_info->tx_offload_capa = BNXT_DEV_TX_OFFLOAD_SUPPORT;
+ dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT;
+
+ /* *INDENT-OFF* */
+ dev_info->default_rxconf = (struct rte_eth_rxconf) {
+ .rx_thresh = {
+ .pthresh = 8,
+ .hthresh = 8,
+ .wthresh = 0,
+ },
+ .rx_free_thresh = 32,
+ /* If no descriptors available, pkts are dropped by default */
+ .rx_drop_en = 1,
+ };
+
+ dev_info->default_txconf = (struct rte_eth_txconf) {
+ .tx_thresh = {
+ .pthresh = 32,
+ .hthresh = 0,
+ .wthresh = 0,
+ },
+ .tx_free_thresh = 32,
+ .tx_rs_thresh = 32,
+ };
+ eth_dev->data->dev_conf.intr_conf.lsc = 1;
+
+ eth_dev->data->dev_conf.intr_conf.rxq = 1;
+ dev_info->rx_desc_lim.nb_min = BNXT_MIN_RING_DESC;
+ dev_info->rx_desc_lim.nb_max = BNXT_MAX_RX_RING_DESC;
+ dev_info->tx_desc_lim.nb_min = BNXT_MIN_RING_DESC;
+ dev_info->tx_desc_lim.nb_max = BNXT_MAX_TX_RING_DESC;
+
+ /* *INDENT-ON* */
+
+ /*
+ * TODO: default_rxconf, default_txconf, rx_desc_lim, and tx_desc_lim
+ * need further investigation.
+ */
+
+ /* VMDq resources */
+ vpool = 64; /* ETH_64_POOLS */
+ vrxq = 128; /* ETH_VMDQ_DCB_NUM_QUEUES */
+ for (i = 0; i < 4; vpool >>= 1, i++) {
+ if (max_vnics > vpool) {
+ for (j = 0; j < 5; vrxq >>= 1, j++) {
+ if (dev_info->max_rx_queues > vrxq) {
+ if (vpool > vrxq)
+ vpool = vrxq;
+ goto found;
+ }
+ }
+ /* Not enough resources to support VMDq */
+ break;
+ }
+ }
+ /* Not enough resources to support VMDq */
+ vpool = 0;
+ vrxq = 0;
+found:
+ dev_info->max_vmdq_pools = vpool;
+ dev_info->vmdq_queue_num = vrxq;
+
+ dev_info->vmdq_pool_base = 0;
+ dev_info->vmdq_queue_base = 0;
+}
+
+/* Configure the device based on the configuration provided */
+static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
+ int rc;
+
+ bp->rx_queues = (void *)eth_dev->data->rx_queues;
+ bp->tx_queues = (void *)eth_dev->data->tx_queues;
+ bp->tx_nr_rings = eth_dev->data->nb_tx_queues;
+ bp->rx_nr_rings = eth_dev->data->nb_rx_queues;
+
+ if (BNXT_VF(bp) && (bp->flags & BNXT_FLAG_NEW_RM)) {
+ rc = bnxt_hwrm_check_vf_rings(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "HWRM insufficient resources\n");
+ return -ENOSPC;
+ }
+
+ rc = bnxt_hwrm_func_reserve_vf_resc(bp, false);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "HWRM resource alloc fail:%x\n", rc);
+ return -ENOSPC;
+ }
+ } else {
+ /* legacy driver needs to get updated values */
+ rc = bnxt_hwrm_func_qcaps(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "hwrm func qcaps fail:%d\n", rc);
+ return rc;
+ }
+ }
+
+ /* Inherit new configurations */
+ if (eth_dev->data->nb_rx_queues > bp->max_rx_rings ||
+ eth_dev->data->nb_tx_queues > bp->max_tx_rings ||
+ eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues >
+ bp->max_cp_rings ||
+ eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues >
+ bp->max_stat_ctx ||
+ (uint32_t)(eth_dev->data->nb_rx_queues) > bp->max_ring_grps ||
+ (!(eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS) &&
+ bp->max_vnics < eth_dev->data->nb_rx_queues)) {
+ PMD_DRV_LOG(ERR,
+ "Insufficient resources to support requested config\n");
+ PMD_DRV_LOG(ERR,
+ "Num Queues Requested: Tx %d, Rx %d\n",
+ eth_dev->data->nb_tx_queues,
+ eth_dev->data->nb_rx_queues);
+ PMD_DRV_LOG(ERR,
+ "MAX: TxQ %d, RxQ %d, CQ %d Stat %d, Grp %d, Vnic %d\n",
+ bp->max_tx_rings, bp->max_rx_rings, bp->max_cp_rings,
+ bp->max_stat_ctx, bp->max_ring_grps, bp->max_vnics);
+ return -ENOSPC;
+ }
+
+ bp->rx_cp_nr_rings = bp->rx_nr_rings;
+ bp->tx_cp_nr_rings = bp->tx_nr_rings;
+
+ if (rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
+ eth_dev->data->mtu =
+ eth_dev->data->dev_conf.rxmode.max_rx_pkt_len -
+ ETHER_HDR_LEN - ETHER_CRC_LEN - VLAN_TAG_SIZE *
+ BNXT_NUM_VLANS;
+ bnxt_mtu_set_op(eth_dev, eth_dev->data->mtu);
+ }
+ return 0;
+}
+
+static void bnxt_print_link_info(struct rte_eth_dev *eth_dev)
+{
+ struct rte_eth_link *link = &eth_dev->data->dev_link;
+
+ if (link->link_status)
+ PMD_DRV_LOG(INFO, "Port %d Link Up - speed %u Mbps - %s\n",
+ eth_dev->data->port_id,
+ (uint32_t)link->link_speed,
+ (link->link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex\n"));
+ else
+ PMD_DRV_LOG(INFO, "Port %d Link Down\n",
+ eth_dev->data->port_id);
+}
+
+static int bnxt_dev_lsc_intr_setup(struct rte_eth_dev *eth_dev)
+{
+ bnxt_print_link_info(eth_dev);
+ return 0;
+}
+
+static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
+ int vlan_mask = 0;
+ int rc;
+
+ if (bp->rx_cp_nr_rings > RTE_ETHDEV_QUEUE_STAT_CNTRS) {
+ PMD_DRV_LOG(ERR,
+ "RxQ cnt %d > CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS %d\n",
+ bp->rx_cp_nr_rings, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ }
+ bp->dev_stopped = 0;
+
+ rc = bnxt_init_chip(bp);
+ if (rc)
+ goto error;
+
+ bnxt_link_update_op(eth_dev, 1);
+
+ if (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
+ vlan_mask |= ETH_VLAN_FILTER_MASK;
+ if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
+ vlan_mask |= ETH_VLAN_STRIP_MASK;
+ rc = bnxt_vlan_offload_set_op(eth_dev, vlan_mask);
+ if (rc)
+ goto error;
+
+ bp->flags |= BNXT_FLAG_INIT_DONE;
+ return 0;
+
+error:
+ bnxt_shutdown_nic(bp);
+ bnxt_free_tx_mbufs(bp);
+ bnxt_free_rx_mbufs(bp);
+ return rc;
+}
+
+static int bnxt_dev_set_link_up_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ int rc = 0;
+
+ if (!bp->link_info.link_up)
+ rc = bnxt_set_hwrm_link_config(bp, true);
+ if (!rc)
+ eth_dev->data->dev_link.link_status = 1;
+
+ bnxt_print_link_info(eth_dev);
+ return 0;
+}
+
+static int bnxt_dev_set_link_down_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ eth_dev->data->dev_link.link_status = 0;
+ bnxt_set_hwrm_link_config(bp, false);
+ bp->link_info.link_up = 0;
+
+ return 0;
+}
+
+/* Unload the driver, release resources */
+static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ bp->flags &= ~BNXT_FLAG_INIT_DONE;
+ if (bp->eth_dev->data->dev_started) {
+ /* TBD: STOP HW queues DMA */
+ eth_dev->data->dev_link.link_status = 0;
+ }
+ bnxt_set_hwrm_link_config(bp, false);
+ bnxt_hwrm_port_clr_stats(bp);
+ bnxt_free_tx_mbufs(bp);
+ bnxt_free_rx_mbufs(bp);
+ bnxt_shutdown_nic(bp);
+ bp->dev_stopped = 1;
+}
+
+static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ if (bp->dev_stopped == 0)
+ bnxt_dev_stop_op(eth_dev);
+
+ bnxt_free_mem(bp);
+ if (eth_dev->data->mac_addrs != NULL) {
+ rte_free(eth_dev->data->mac_addrs);
+ eth_dev->data->mac_addrs = NULL;
+ }
+ if (bp->grp_info != NULL) {
+ rte_free(bp->grp_info);
+ bp->grp_info = NULL;
+ }
+
+ bnxt_dev_uninit(eth_dev);
+}
+
+static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev,
+ uint32_t index)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ uint64_t pool_mask = eth_dev->data->mac_pool_sel[index];
+ struct bnxt_vnic_info *vnic;
+ struct bnxt_filter_info *filter, *temp_filter;
+ uint32_t pool = RTE_MIN(MAX_FF_POOLS, ETH_64_POOLS);
+ uint32_t i;
+
+ /*
+ * Loop through all VNICs from the specified filter flow pools to
+ * remove the corresponding MAC addr filter
+ */
+ for (i = 0; i < pool; i++) {
+ if (!(pool_mask & (1ULL << i)))
+ continue;
+
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ filter = STAILQ_FIRST(&vnic->filter);
+ while (filter) {
+ temp_filter = STAILQ_NEXT(filter, next);
+ if (filter->mac_index == index) {
+ STAILQ_REMOVE(&vnic->filter, filter,
+ bnxt_filter_info, next);
+ bnxt_hwrm_clear_l2_filter(bp, filter);
+ filter->mac_index = INVALID_MAC_INDEX;
+ memset(&filter->l2_addr, 0,
+ ETHER_ADDR_LEN);
+ STAILQ_INSERT_TAIL(
+ &bp->free_filter_list,
+ filter, next);
+ }
+ filter = temp_filter;
+ }
+ }
+ }
+}
+
+static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,
+ struct ether_addr *mac_addr,
+ uint32_t index, uint32_t pool)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic = STAILQ_FIRST(&bp->ff_pool[pool]);
+ struct bnxt_filter_info *filter;
+
+ if (BNXT_VF(bp)) {
+ PMD_DRV_LOG(ERR, "Cannot add MAC address to a VF interface\n");
+ return -ENOTSUP;
+ }
+
+ if (!vnic) {
+ PMD_DRV_LOG(ERR, "VNIC not found for pool %d!\n", pool);
+ return -EINVAL;
+ }
+ /* Attach requested MAC address to the new l2_filter */
+ STAILQ_FOREACH(filter, &vnic->filter, next) {
+ if (filter->mac_index == index) {
+ PMD_DRV_LOG(ERR,
+ "MAC addr already existed for pool %d\n", pool);
+ return 0;
+ }
+ }
+ filter = bnxt_alloc_filter(bp);
+ if (!filter) {
+ PMD_DRV_LOG(ERR, "L2 filter alloc failed\n");
+ return -ENODEV;
+ }
+ STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+ filter->mac_index = index;
+ memcpy(filter->l2_addr, mac_addr, ETHER_ADDR_LEN);
+ return bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
+}
+
+int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
+{
+ int rc = 0;
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct rte_eth_link new;
+ unsigned int cnt = BNXT_LINK_WAIT_CNT;
+
+ memset(&new, 0, sizeof(new));
+ do {
+ /* Retrieve link info from hardware */
+ rc = bnxt_get_hwrm_link_config(bp, &new);
+ if (rc) {
+ new.link_speed = ETH_LINK_SPEED_100M;
+ new.link_duplex = ETH_LINK_FULL_DUPLEX;
+ PMD_DRV_LOG(ERR,
+ "Failed to retrieve link rc = 0x%x!\n", rc);
+ goto out;
+ }
+ rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
+
+ if (!wait_to_complete)
+ break;
+ } while (!new.link_status && cnt--);
+
+out:
+ /* Timed out or success */
+ if (new.link_status != eth_dev->data->dev_link.link_status ||
+ new.link_speed != eth_dev->data->dev_link.link_speed) {
+ memcpy(&eth_dev->data->dev_link, &new,
+ sizeof(struct rte_eth_link));
+
+ _rte_eth_dev_callback_process(eth_dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
+
+ bnxt_print_link_info(eth_dev);
+ }
+
+ return rc;
+}
+
+static void bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ vnic = &bp->vnic_info[0];
+
+ vnic->flags |= BNXT_VNIC_INFO_PROMISC;
+ bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+}
+
+static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ vnic = &bp->vnic_info[0];
+
+ vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
+ bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+}
+
+static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ vnic = &bp->vnic_info[0];
+
+ vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
+ bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+}
+
+static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ vnic = &bp->vnic_info[0];
+
+ vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
+ bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+}
+
+static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ struct bnxt_vnic_info *vnic;
+ int i;
+
+ if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG))
+ return -EINVAL;
+
+ if (reta_size != HW_HASH_INDEX_SIZE) {
+ PMD_DRV_LOG(ERR, "The configured hash table lookup size "
+ "(%d) must equal the size supported by the hardware "
+ "(%d)\n", reta_size, HW_HASH_INDEX_SIZE);
+ return -EINVAL;
+ }
+ /* Update the RSS VNIC(s) */
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ memcpy(vnic->rss_table, reta_conf, reta_size);
+
+ bnxt_hwrm_vnic_rss_cfg(bp, vnic);
+ }
+ }
+ return 0;
+}
+
+static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+ struct rte_intr_handle *intr_handle
+ = &bp->pdev->intr_handle;
+
+ /* Retrieve from the default VNIC */
+ if (!vnic)
+ return -EINVAL;
+ if (!vnic->rss_table)
+ return -EINVAL;
+
+ if (reta_size != HW_HASH_INDEX_SIZE) {
+ PMD_DRV_LOG(ERR, "The configured hash table lookup size "
+ "(%d) must equal the size supported by the hardware "
+ "(%d)\n", reta_size, HW_HASH_INDEX_SIZE);
+ return -EINVAL;
+ }
+ /* EW - need to revisit here copying from uint64_t to uint16_t */
+ memcpy(reta_conf, vnic->rss_table, reta_size);
+
+ if (rte_intr_allow_others(intr_handle)) {
+ if (eth_dev->data->dev_conf.intr_conf.lsc != 0)
+ bnxt_dev_lsc_intr_setup(eth_dev);
+ }
+
+ return 0;
+}
+
+static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ struct bnxt_vnic_info *vnic;
+ uint16_t hash_type = 0;
+ int i;
+
+ /*
+ * If RSS enablement were different than dev_configure,
+ * then return -EINVAL
+ */
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) {
+ if (!rss_conf->rss_hf)
+ PMD_DRV_LOG(ERR, "Hash type NONE\n");
+ } else {
+ if (rss_conf->rss_hf & BNXT_ETH_RSS_SUPPORT)
+ return -EINVAL;
+ }
+
+ bp->flags |= BNXT_FLAG_UPDATE_HASH;
+ memcpy(&bp->rss_conf, rss_conf, sizeof(*rss_conf));
+
+ if (rss_conf->rss_hf & ETH_RSS_IPV4)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+ if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
+ if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
+ if (rss_conf->rss_hf & ETH_RSS_IPV6)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+ if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
+ if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_UDP)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
+
+ /* Update the RSS VNIC(s) */
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ vnic->hash_type = hash_type;
+
+ /*
+ * Use the supplied key if the key length is
+ * acceptable and the rss_key is not NULL
+ */
+ if (rss_conf->rss_key &&
+ rss_conf->rss_key_len <= HW_HASH_KEY_SIZE)
+ memcpy(vnic->rss_hash_key, rss_conf->rss_key,
+ rss_conf->rss_key_len);
+
+ bnxt_hwrm_vnic_rss_cfg(bp, vnic);
+ }
+ }
+ return 0;
+}
+
+static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+ int len;
+ uint32_t hash_types;
+
+ /* RSS configuration is the same for all VNICs */
+ if (vnic && vnic->rss_hash_key) {
+ if (rss_conf->rss_key) {
+ len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ?
+ rss_conf->rss_key_len : HW_HASH_KEY_SIZE;
+ memcpy(rss_conf->rss_key, vnic->rss_hash_key, len);
+ }
+
+ hash_types = vnic->hash_type;
+ rss_conf->rss_hf = 0;
+ if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) {
+ rss_conf->rss_hf |= ETH_RSS_IPV4;
+ hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+ }
+ if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) {
+ rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
+ hash_types &=
+ ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
+ }
+ if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) {
+ rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
+ hash_types &=
+ ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
+ }
+ if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) {
+ rss_conf->rss_hf |= ETH_RSS_IPV6;
+ hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+ }
+ if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) {
+ rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
+ hash_types &=
+ ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
+ }
+ if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) {
+ rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
+ hash_types &=
+ ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
+ }
+ if (hash_types) {
+ PMD_DRV_LOG(ERR,
+ "Unknwon RSS config from firmware (%08x), RSS disabled",
+ vnic->hash_type);
+ return -ENOTSUP;
+ }
+ } else {
+ rss_conf->rss_hf = 0;
+ }
+ return 0;
+}
+
+static int bnxt_flow_ctrl_get_op(struct rte_eth_dev *dev,
+ struct rte_eth_fc_conf *fc_conf)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct rte_eth_link link_info;
+ int rc;
+
+ rc = bnxt_get_hwrm_link_config(bp, &link_info);
+ if (rc)
+ return rc;
+
+ memset(fc_conf, 0, sizeof(*fc_conf));
+ if (bp->link_info.auto_pause)
+ fc_conf->autoneg = 1;
+ switch (bp->link_info.pause) {
+ case 0:
+ fc_conf->mode = RTE_FC_NONE;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX:
+ fc_conf->mode = RTE_FC_TX_PAUSE;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX:
+ fc_conf->mode = RTE_FC_RX_PAUSE;
+ break;
+ case (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX |
+ HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX):
+ fc_conf->mode = RTE_FC_FULL;
+ break;
+ }
+ return 0;
+}
+
+static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,
+ struct rte_eth_fc_conf *fc_conf)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+ if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) {
+ PMD_DRV_LOG(ERR, "Flow Control Settings cannot be modified\n");
+ return -ENOTSUP;
+ }
+
+ switch (fc_conf->mode) {
+ case RTE_FC_NONE:
+ bp->link_info.auto_pause = 0;
+ bp->link_info.force_pause = 0;
+ break;
+ case RTE_FC_RX_PAUSE:
+ if (fc_conf->autoneg) {
+ bp->link_info.auto_pause =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
+ bp->link_info.force_pause = 0;
+ } else {
+ bp->link_info.auto_pause = 0;
+ bp->link_info.force_pause =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;
+ }
+ break;
+ case RTE_FC_TX_PAUSE:
+ if (fc_conf->autoneg) {
+ bp->link_info.auto_pause =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX;
+ bp->link_info.force_pause = 0;
+ } else {
+ bp->link_info.auto_pause = 0;
+ bp->link_info.force_pause =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX;
+ }
+ break;
+ case RTE_FC_FULL:
+ if (fc_conf->autoneg) {
+ bp->link_info.auto_pause =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX |
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
+ bp->link_info.force_pause = 0;
+ } else {
+ bp->link_info.auto_pause = 0;
+ bp->link_info.force_pause =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX |
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;
+ }
+ break;
+ }
+ return bnxt_set_hwrm_link_config(bp, true);
+}
+
+/* Add UDP tunneling port */
+static int
+bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_udp_tunnel *udp_tunnel)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ uint16_t tunnel_type = 0;
+ int rc = 0;
+
+ switch (udp_tunnel->prot_type) {
+ case RTE_TUNNEL_TYPE_VXLAN:
+ if (bp->vxlan_port_cnt) {
+ PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n",
+ udp_tunnel->udp_port);
+ if (bp->vxlan_port != udp_tunnel->udp_port) {
+ PMD_DRV_LOG(ERR, "Only one port allowed\n");
+ return -ENOSPC;
+ }
+ bp->vxlan_port_cnt++;
+ return 0;
+ }
+ tunnel_type =
+ HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;
+ bp->vxlan_port_cnt++;
+ break;
+ case RTE_TUNNEL_TYPE_GENEVE:
+ if (bp->geneve_port_cnt) {
+ PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n",
+ udp_tunnel->udp_port);
+ if (bp->geneve_port != udp_tunnel->udp_port) {
+ PMD_DRV_LOG(ERR, "Only one port allowed\n");
+ return -ENOSPC;
+ }
+ bp->geneve_port_cnt++;
+ return 0;
+ }
+ tunnel_type =
+ HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE;
+ bp->geneve_port_cnt++;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Tunnel type is not supported\n");
+ return -ENOTSUP;
+ }
+ rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port,
+ tunnel_type);
+ return rc;
+}
+
+static int
+bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_udp_tunnel *udp_tunnel)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ uint16_t tunnel_type = 0;
+ uint16_t port = 0;
+ int rc = 0;
+
+ switch (udp_tunnel->prot_type) {
+ case RTE_TUNNEL_TYPE_VXLAN:
+ if (!bp->vxlan_port_cnt) {
+ PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n");
+ return -EINVAL;
+ }
+ if (bp->vxlan_port != udp_tunnel->udp_port) {
+ PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n",
+ udp_tunnel->udp_port, bp->vxlan_port);
+ return -EINVAL;
+ }
+ if (--bp->vxlan_port_cnt)
+ return 0;
+
+ tunnel_type =
+ HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN;
+ port = bp->vxlan_fw_dst_port_id;
+ break;
+ case RTE_TUNNEL_TYPE_GENEVE:
+ if (!bp->geneve_port_cnt) {
+ PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n");
+ return -EINVAL;
+ }
+ if (bp->geneve_port != udp_tunnel->udp_port) {
+ PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n",
+ udp_tunnel->udp_port, bp->geneve_port);
+ return -EINVAL;
+ }
+ if (--bp->geneve_port_cnt)
+ return 0;
+
+ tunnel_type =
+ HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE;
+ port = bp->geneve_fw_dst_port_id;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Tunnel type is not supported\n");
+ return -ENOTSUP;
+ }
+
+ rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type);
+ if (!rc) {
+ if (tunnel_type ==
+ HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN)
+ bp->vxlan_port = 0;
+ if (tunnel_type ==
+ HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE)
+ bp->geneve_port = 0;
+ }
+ return rc;
+}
+
+static int bnxt_del_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
+{
+ struct bnxt_filter_info *filter, *temp_filter, *new_filter;
+ struct bnxt_vnic_info *vnic;
+ unsigned int i;
+ int rc = 0;
+ uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN;
+
+ /* Cycle through all VNICs */
+ for (i = 0; i < bp->nr_vnics; i++) {
+ /*
+ * For each VNIC and each associated filter(s)
+ * if VLAN exists && VLAN matches vlan_id
+ * remove the MAC+VLAN filter
+ * add a new MAC only filter
+ * else
+ * VLAN filter doesn't exist, just skip and continue
+ */
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ filter = STAILQ_FIRST(&vnic->filter);
+ while (filter) {
+ temp_filter = STAILQ_NEXT(filter, next);
+
+ if (filter->enables & chk &&
+ filter->l2_ovlan == vlan_id) {
+ /* Must delete the filter */
+ STAILQ_REMOVE(&vnic->filter, filter,
+ bnxt_filter_info, next);
+ bnxt_hwrm_clear_l2_filter(bp, filter);
+ STAILQ_INSERT_TAIL(
+ &bp->free_filter_list,
+ filter, next);
+
+ /*
+ * Need to examine to see if the MAC
+ * filter already existed or not before
+ * allocating a new one
+ */
+
+ new_filter = bnxt_alloc_filter(bp);
+ if (!new_filter) {
+ PMD_DRV_LOG(ERR,
+ "MAC/VLAN filter alloc failed\n");
+ rc = -ENOMEM;
+ goto exit;
+ }
+ STAILQ_INSERT_TAIL(&vnic->filter,
+ new_filter, next);
+ /* Inherit MAC from previous filter */
+ new_filter->mac_index =
+ filter->mac_index;
+ memcpy(new_filter->l2_addr,
+ filter->l2_addr, ETHER_ADDR_LEN);
+ /* MAC only filter */
+ rc = bnxt_hwrm_set_l2_filter(bp,
+ vnic->fw_vnic_id,
+ new_filter);
+ if (rc)
+ goto exit;
+ PMD_DRV_LOG(INFO,
+ "Del Vlan filter for %d\n",
+ vlan_id);
+ }
+ filter = temp_filter;
+ }
+ }
+ }
+exit:
+ return rc;
+}
+
+static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
+{
+ struct bnxt_filter_info *filter, *temp_filter, *new_filter;
+ struct bnxt_vnic_info *vnic;
+ unsigned int i;
+ int rc = 0;
+ uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN |
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK;
+ uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN;
+
+ /* Cycle through all VNICs */
+ for (i = 0; i < bp->nr_vnics; i++) {
+ /*
+ * For each VNIC and each associated filter(s)
+ * if VLAN exists:
+ * if VLAN matches vlan_id
+ * VLAN filter already exists, just skip and continue
+ * else
+ * add a new MAC+VLAN filter
+ * else
+ * Remove the old MAC only filter
+ * Add a new MAC+VLAN filter
+ */
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ filter = STAILQ_FIRST(&vnic->filter);
+ while (filter) {
+ temp_filter = STAILQ_NEXT(filter, next);
+
+ if (filter->enables & chk) {
+ if (filter->l2_ovlan == vlan_id)
+ goto cont;
+ } else {
+ /* Must delete the MAC filter */
+ STAILQ_REMOVE(&vnic->filter, filter,
+ bnxt_filter_info, next);
+ bnxt_hwrm_clear_l2_filter(bp, filter);
+ filter->l2_ovlan = 0;
+ STAILQ_INSERT_TAIL(
+ &bp->free_filter_list,
+ filter, next);
+ }
+ new_filter = bnxt_alloc_filter(bp);
+ if (!new_filter) {
+ PMD_DRV_LOG(ERR,
+ "MAC/VLAN filter alloc failed\n");
+ rc = -ENOMEM;
+ goto exit;
+ }
+ STAILQ_INSERT_TAIL(&vnic->filter, new_filter,
+ next);
+ /* Inherit MAC from the previous filter */
+ new_filter->mac_index = filter->mac_index;
+ memcpy(new_filter->l2_addr, filter->l2_addr,
+ ETHER_ADDR_LEN);
+ /* MAC + VLAN ID filter */
+ new_filter->l2_ivlan = vlan_id;
+ new_filter->l2_ivlan_mask = 0xF000;
+ new_filter->enables |= en;
+ rc = bnxt_hwrm_set_l2_filter(bp,
+ vnic->fw_vnic_id,
+ new_filter);
+ if (rc)
+ goto exit;
+ PMD_DRV_LOG(INFO,
+ "Added Vlan filter for %d\n", vlan_id);
+cont:
+ filter = temp_filter;
+ }
+ }
+ }
+exit:
+ return rc;
+}
+
+static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev,
+ uint16_t vlan_id, int on)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ /* These operations apply to ALL existing MAC/VLAN filters */
+ if (on)
+ return bnxt_add_vlan_filter(bp, vlan_id);
+ else
+ return bnxt_del_vlan_filter(bp, vlan_id);
+}
+
+static int
+bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
+ unsigned int i;
+
+ if (mask & ETH_VLAN_FILTER_MASK) {
+ if (!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)) {
+ /* Remove any VLAN filters programmed */
+ for (i = 0; i < 4095; i++)
+ bnxt_del_vlan_filter(bp, i);
+ }
+ PMD_DRV_LOG(DEBUG, "VLAN Filtering: %d\n",
+ !!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER));
+ }
+
+ if (mask & ETH_VLAN_STRIP_MASK) {
+ /* Enable or disable VLAN stripping */
+ for (i = 0; i < bp->nr_vnics; i++) {
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+ if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
+ vnic->vlan_strip = true;
+ else
+ vnic->vlan_strip = false;
+ bnxt_hwrm_vnic_cfg(bp, vnic);
+ }
+ PMD_DRV_LOG(DEBUG, "VLAN Strip Offload: %d\n",
+ !!(rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP));
+ }
+
+ if (mask & ETH_VLAN_EXTEND_MASK)
+ PMD_DRV_LOG(ERR, "Extend VLAN Not supported\n");
+
+ return 0;
+}
+
+static int
+bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ /* Default Filter is tied to VNIC 0 */
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+ struct bnxt_filter_info *filter;
+ int rc;
+
+ if (BNXT_VF(bp))
+ return -EPERM;
+
+ memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
+
+ STAILQ_FOREACH(filter, &vnic->filter, next) {
+ /* Default Filter is at Index 0 */
+ if (filter->mac_index != 0)
+ continue;
+ rc = bnxt_hwrm_clear_l2_filter(bp, filter);
+ if (rc)
+ return rc;
+ memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
+ memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+ filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
+ filter->enables |=
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
+ rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
+ if (rc)
+ return rc;
+ filter->mac_index = 0;
+ PMD_DRV_LOG(DEBUG, "Set MAC addr\n");
+ }
+
+ return 0;
+}
+
+static int
+bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
+ struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ char *mc_addr_list = (char *)mc_addr_set;
+ struct bnxt_vnic_info *vnic;
+ uint32_t off = 0, i = 0;
+
+ vnic = &bp->vnic_info[0];
+
+ if (nb_mc_addr > BNXT_MAX_MC_ADDRS) {
+ vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
+ goto allmulti;
+ }
+
+ /* TODO Check for Duplicate mcast addresses */
+ vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
+ for (i = 0; i < nb_mc_addr; i++) {
+ memcpy(vnic->mc_list + off, &mc_addr_list[i], ETHER_ADDR_LEN);
+ off += ETHER_ADDR_LEN;
+ }
+
+ vnic->mc_addr_cnt = i;
+
+allmulti:
+ return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+}
+
+static int
+bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ uint8_t fw_major = (bp->fw_ver >> 24) & 0xff;
+ uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff;
+ uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff;
+ int ret;
+
+ ret = snprintf(fw_version, fw_size, "%d.%d.%d",
+ fw_major, fw_minor, fw_updt);
+
+ ret += 1; /* add the size of '\0' */
+ if (fw_size < (uint32_t)ret)
+ return ret;
+ else
+ return 0;
+}
+
+static void
+bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
+ struct rte_eth_rxq_info *qinfo)
+{
+ struct bnxt_rx_queue *rxq;
+
+ rxq = dev->data->rx_queues[queue_id];
+
+ qinfo->mp = rxq->mb_pool;
+ qinfo->scattered_rx = dev->data->scattered_rx;
+ qinfo->nb_desc = rxq->nb_rx_desc;
+
+ qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
+ qinfo->conf.rx_drop_en = 0;
+ qinfo->conf.rx_deferred_start = 0;
+}
+
+static void
+bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
+ struct rte_eth_txq_info *qinfo)
+{
+ struct bnxt_tx_queue *txq;
+
+ txq = dev->data->tx_queues[queue_id];
+
+ qinfo->nb_desc = txq->nb_tx_desc;
+
+ qinfo->conf.tx_thresh.pthresh = txq->pthresh;
+ qinfo->conf.tx_thresh.hthresh = txq->hthresh;
+ qinfo->conf.tx_thresh.wthresh = txq->wthresh;
+
+ qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
+ qinfo->conf.tx_rs_thresh = 0;
+ qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
+}
+
+static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
+{
+ struct bnxt *bp = eth_dev->data->dev_private;
+ struct rte_eth_dev_info dev_info;
+ uint32_t max_dev_mtu;
+ uint32_t rc = 0;
+ uint32_t i;
+
+ bnxt_dev_info_get_op(eth_dev, &dev_info);
+ max_dev_mtu = dev_info.max_rx_pktlen -
+ ETHER_HDR_LEN - ETHER_CRC_LEN - VLAN_TAG_SIZE * 2;
+
+ if (new_mtu < ETHER_MIN_MTU || new_mtu > max_dev_mtu) {
+ PMD_DRV_LOG(ERR, "MTU requested must be within (%d, %d)\n",
+ ETHER_MIN_MTU, max_dev_mtu);
+ return -EINVAL;
+ }
+
+
+ if (new_mtu > ETHER_MTU) {
+ bp->flags |= BNXT_FLAG_JUMBO;
+ bp->eth_dev->data->dev_conf.rxmode.offloads |=
+ DEV_RX_OFFLOAD_JUMBO_FRAME;
+ } else {
+ bp->eth_dev->data->dev_conf.rxmode.offloads &=
+ ~DEV_RX_OFFLOAD_JUMBO_FRAME;
+ bp->flags &= ~BNXT_FLAG_JUMBO;
+ }
+
+ eth_dev->data->dev_conf.rxmode.max_rx_pkt_len =
+ new_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
+
+ eth_dev->data->mtu = new_mtu;
+ PMD_DRV_LOG(INFO, "New MTU is %d\n", eth_dev->data->mtu);
+
+ for (i = 0; i < bp->nr_vnics; i++) {
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+ uint16_t size = 0;
+
+ vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+ ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
+ rc = bnxt_hwrm_vnic_cfg(bp, vnic);
+ if (rc)
+ break;
+
+ size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
+ size -= RTE_PKTMBUF_HEADROOM;
+
+ if (size < new_mtu) {
+ rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+ if (rc)
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
+static int
+bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ uint16_t vlan = bp->vlan;
+ int rc;
+
+ if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "PVID cannot be modified for this function\n");
+ return -ENOTSUP;
+ }
+ bp->vlan = on ? pvid : 0;
+
+ rc = bnxt_hwrm_set_default_vlan(bp, 0, 0);
+ if (rc)
+ bp->vlan = vlan;
+ return rc;
+}
+
+static int
+bnxt_dev_led_on_op(struct rte_eth_dev *dev)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+ return bnxt_hwrm_port_led_cfg(bp, true);
+}
+
+static int
+bnxt_dev_led_off_op(struct rte_eth_dev *dev)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+ return bnxt_hwrm_port_led_cfg(bp, false);
+}
+
+static uint32_t
+bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ uint32_t desc = 0, raw_cons = 0, cons;
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_rx_queue *rxq;
+ struct rx_pkt_cmpl *rxcmp;
+ uint16_t cmp_type;
+ uint8_t cmp = 1;
+ bool valid;
+
+ rxq = dev->data->rx_queues[rx_queue_id];
+ cpr = rxq->cp_ring;
+ valid = cpr->valid;
+
+ while (raw_cons < rxq->nb_rx_desc) {
+ cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
+ rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
+
+ if (!CMPL_VALID(rxcmp, valid))
+ goto nothing_to_do;
+ valid = FLIP_VALID(cons, cpr->cp_ring_struct->ring_mask, valid);
+ cmp_type = CMP_TYPE(rxcmp);
+ if (cmp_type == RX_TPA_END_CMPL_TYPE_RX_TPA_END) {
+ cmp = (rte_le_to_cpu_32(
+ ((struct rx_tpa_end_cmpl *)
+ (rxcmp))->agg_bufs_v1) &
+ RX_TPA_END_CMPL_AGG_BUFS_MASK) >>
+ RX_TPA_END_CMPL_AGG_BUFS_SFT;
+ desc++;
+ } else if (cmp_type == 0x11) {
+ desc++;
+ cmp = (rxcmp->agg_bufs_v1 &
+ RX_PKT_CMPL_AGG_BUFS_MASK) >>
+ RX_PKT_CMPL_AGG_BUFS_SFT;
+ } else {
+ cmp = 1;
+ }
+nothing_to_do:
+ raw_cons += cmp ? cmp : 2;
+ }
+
+ return desc;
+}
+
+static int
+bnxt_rx_descriptor_status_op(void *rx_queue, uint16_t offset)
+{
+ struct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue;
+ struct bnxt_rx_ring_info *rxr;
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_sw_rx_bd *rx_buf;
+ struct rx_pkt_cmpl *rxcmp;
+ uint32_t cons, cp_cons;
+
+ if (!rxq)
+ return -EINVAL;
+
+ cpr = rxq->cp_ring;
+ rxr = rxq->rx_ring;
+
+ if (offset >= rxq->nb_rx_desc)
+ return -EINVAL;
+
+ cons = RING_CMP(cpr->cp_ring_struct, offset);
+ cp_cons = cpr->cp_raw_cons;
+ rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
+
+ if (cons > cp_cons) {
+ if (CMPL_VALID(rxcmp, cpr->valid))
+ return RTE_ETH_RX_DESC_DONE;
+ } else {
+ if (CMPL_VALID(rxcmp, !cpr->valid))
+ return RTE_ETH_RX_DESC_DONE;
+ }
+ rx_buf = &rxr->rx_buf_ring[cons];
+ if (rx_buf->mbuf == NULL)
+ return RTE_ETH_RX_DESC_UNAVAIL;
+
+
+ return RTE_ETH_RX_DESC_AVAIL;
+}
+
+static int
+bnxt_tx_descriptor_status_op(void *tx_queue, uint16_t offset)
+{
+ struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue;
+ struct bnxt_tx_ring_info *txr;
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_sw_tx_bd *tx_buf;
+ struct tx_pkt_cmpl *txcmp;
+ uint32_t cons, cp_cons;
+
+ if (!txq)
+ return -EINVAL;
+
+ cpr = txq->cp_ring;
+ txr = txq->tx_ring;
+
+ if (offset >= txq->nb_tx_desc)
+ return -EINVAL;
+
+ cons = RING_CMP(cpr->cp_ring_struct, offset);
+ txcmp = (struct tx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
+ cp_cons = cpr->cp_raw_cons;
+
+ if (cons > cp_cons) {
+ if (CMPL_VALID(txcmp, cpr->valid))
+ return RTE_ETH_TX_DESC_UNAVAIL;
+ } else {
+ if (CMPL_VALID(txcmp, !cpr->valid))
+ return RTE_ETH_TX_DESC_UNAVAIL;
+ }
+ tx_buf = &txr->tx_buf_ring[cons];
+ if (tx_buf->mbuf == NULL)
+ return RTE_ETH_TX_DESC_DONE;
+
+ return RTE_ETH_TX_DESC_FULL;
+}
+
+static struct bnxt_filter_info *
+bnxt_match_and_validate_ether_filter(struct bnxt *bp,
+ struct rte_eth_ethertype_filter *efilter,
+ struct bnxt_vnic_info *vnic0,
+ struct bnxt_vnic_info *vnic,
+ int *ret)
+{
+ struct bnxt_filter_info *mfilter = NULL;
+ int match = 0;
+ *ret = 0;
+
+ if (efilter->ether_type == ETHER_TYPE_IPv4 ||
+ efilter->ether_type == ETHER_TYPE_IPv6) {
+ PMD_DRV_LOG(ERR, "invalid ether_type(0x%04x) in"
+ " ethertype filter.", efilter->ether_type);
+ *ret = -EINVAL;
+ goto exit;
+ }
+ if (efilter->queue >= bp->rx_nr_rings) {
+ PMD_DRV_LOG(ERR, "Invalid queue %d\n", efilter->queue);
+ *ret = -EINVAL;
+ goto exit;
+ }
+
+ vnic0 = STAILQ_FIRST(&bp->ff_pool[0]);
+ vnic = STAILQ_FIRST(&bp->ff_pool[efilter->queue]);
+ if (vnic == NULL) {
+ PMD_DRV_LOG(ERR, "Invalid queue %d\n", efilter->queue);
+ *ret = -EINVAL;
+ goto exit;
+ }
+
+ if (efilter->flags & RTE_ETHTYPE_FLAGS_DROP) {
+ STAILQ_FOREACH(mfilter, &vnic0->filter, next) {
+ if ((!memcmp(efilter->mac_addr.addr_bytes,
+ mfilter->l2_addr, ETHER_ADDR_LEN) &&
+ mfilter->flags ==
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP &&
+ mfilter->ethertype == efilter->ether_type)) {
+ match = 1;
+ break;
+ }
+ }
+ } else {
+ STAILQ_FOREACH(mfilter, &vnic->filter, next)
+ if ((!memcmp(efilter->mac_addr.addr_bytes,
+ mfilter->l2_addr, ETHER_ADDR_LEN) &&
+ mfilter->ethertype == efilter->ether_type &&
+ mfilter->flags ==
+ HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX)) {
+ match = 1;
+ break;
+ }
+ }
+
+ if (match)
+ *ret = -EEXIST;
+
+exit:
+ return mfilter;
+}
+
+static int
+bnxt_ethertype_filter(struct rte_eth_dev *dev,
+ enum rte_filter_op filter_op,
+ void *arg)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct rte_eth_ethertype_filter *efilter =
+ (struct rte_eth_ethertype_filter *)arg;
+ struct bnxt_filter_info *bfilter, *filter1;
+ struct bnxt_vnic_info *vnic, *vnic0;
+ int ret;
+
+ if (filter_op == RTE_ETH_FILTER_NOP)
+ return 0;
+
+ if (arg == NULL) {
+ PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
+ filter_op);
+ return -EINVAL;
+ }
+
+ vnic0 = STAILQ_FIRST(&bp->ff_pool[0]);
+ vnic = STAILQ_FIRST(&bp->ff_pool[efilter->queue]);
+
+ switch (filter_op) {
+ case RTE_ETH_FILTER_ADD:
+ bnxt_match_and_validate_ether_filter(bp, efilter,
+ vnic0, vnic, &ret);
+ if (ret < 0)
+ return ret;
+
+ bfilter = bnxt_get_unused_filter(bp);
+ if (bfilter == NULL) {
+ PMD_DRV_LOG(ERR,
+ "Not enough resources for a new filter.\n");
+ return -ENOMEM;
+ }
+ bfilter->filter_type = HWRM_CFA_NTUPLE_FILTER;
+ memcpy(bfilter->l2_addr, efilter->mac_addr.addr_bytes,
+ ETHER_ADDR_LEN);
+ memcpy(bfilter->dst_macaddr, efilter->mac_addr.addr_bytes,
+ ETHER_ADDR_LEN);
+ bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR;
+ bfilter->ethertype = efilter->ether_type;
+ bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
+
+ filter1 = bnxt_get_l2_filter(bp, bfilter, vnic0);
+ if (filter1 == NULL) {
+ ret = -1;
+ goto cleanup;
+ }
+ bfilter->enables |=
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID;
+ bfilter->fw_l2_filter_id = filter1->fw_l2_filter_id;
+
+ bfilter->dst_id = vnic->fw_vnic_id;
+
+ if (efilter->flags & RTE_ETHTYPE_FLAGS_DROP) {
+ bfilter->flags =
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP;
+ }
+
+ ret = bnxt_hwrm_set_ntuple_filter(bp, bfilter->dst_id, bfilter);
+ if (ret)
+ goto cleanup;
+ STAILQ_INSERT_TAIL(&vnic->filter, bfilter, next);
+ break;
+ case RTE_ETH_FILTER_DELETE:
+ filter1 = bnxt_match_and_validate_ether_filter(bp, efilter,
+ vnic0, vnic, &ret);
+ if (ret == -EEXIST) {
+ ret = bnxt_hwrm_clear_ntuple_filter(bp, filter1);
+
+ STAILQ_REMOVE(&vnic->filter, filter1, bnxt_filter_info,
+ next);
+ bnxt_free_filter(bp, filter1);
+ } else if (ret == 0) {
+ PMD_DRV_LOG(ERR, "No matching filter found\n");
+ }
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
+ ret = -EINVAL;
+ goto error;
+ }
+ return ret;
+cleanup:
+ bnxt_free_filter(bp, bfilter);
+error:
+ return ret;
+}
+
+static inline int
+parse_ntuple_filter(struct bnxt *bp,
+ struct rte_eth_ntuple_filter *nfilter,
+ struct bnxt_filter_info *bfilter)
+{
+ uint32_t en = 0;
+
+ if (nfilter->queue >= bp->rx_nr_rings) {
+ PMD_DRV_LOG(ERR, "Invalid queue %d\n", nfilter->queue);
+ return -EINVAL;
+ }
+
+ switch (nfilter->dst_port_mask) {
+ case UINT16_MAX:
+ bfilter->dst_port_mask = -1;
+ bfilter->dst_port = nfilter->dst_port;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT |
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid dst_port mask.");
+ return -EINVAL;
+ }
+
+ bfilter->ip_addr_type = NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4;
+ en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
+
+ switch (nfilter->proto_mask) {
+ case UINT8_MAX:
+ if (nfilter->proto == 17) /* IPPROTO_UDP */
+ bfilter->ip_protocol = 17;
+ else if (nfilter->proto == 6) /* IPPROTO_TCP */
+ bfilter->ip_protocol = 6;
+ else
+ return -EINVAL;
+ en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid protocol mask.");
+ return -EINVAL;
+ }
+
+ switch (nfilter->dst_ip_mask) {
+ case UINT32_MAX:
+ bfilter->dst_ipaddr_mask[0] = -1;
+ bfilter->dst_ipaddr[0] = nfilter->dst_ip;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR |
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid dst_ip mask.");
+ return -EINVAL;
+ }
+
+ switch (nfilter->src_ip_mask) {
+ case UINT32_MAX:
+ bfilter->src_ipaddr_mask[0] = -1;
+ bfilter->src_ipaddr[0] = nfilter->src_ip;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR |
+ NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid src_ip mask.");
+ return -EINVAL;
+ }
+
+ switch (nfilter->src_port_mask) {
+ case UINT16_MAX:
+ bfilter->src_port_mask = -1;
+ bfilter->src_port = nfilter->src_port;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT |
+ NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid src_port mask.");
+ return -EINVAL;
+ }
+
+ //TODO Priority
+ //nfilter->priority = (uint8_t)filter->priority;
+
+ bfilter->enables = en;
+ return 0;
+}
+
+static struct bnxt_filter_info*
+bnxt_match_ntuple_filter(struct bnxt *bp,
+ struct bnxt_filter_info *bfilter,
+ struct bnxt_vnic_info **mvnic)
+{
+ struct bnxt_filter_info *mfilter = NULL;
+ int i;
+
+ for (i = bp->nr_vnics - 1; i >= 0; i--) {
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+ STAILQ_FOREACH(mfilter, &vnic->filter, next) {
+ if (bfilter->src_ipaddr[0] == mfilter->src_ipaddr[0] &&
+ bfilter->src_ipaddr_mask[0] ==
+ mfilter->src_ipaddr_mask[0] &&
+ bfilter->src_port == mfilter->src_port &&
+ bfilter->src_port_mask == mfilter->src_port_mask &&
+ bfilter->dst_ipaddr[0] == mfilter->dst_ipaddr[0] &&
+ bfilter->dst_ipaddr_mask[0] ==
+ mfilter->dst_ipaddr_mask[0] &&
+ bfilter->dst_port == mfilter->dst_port &&
+ bfilter->dst_port_mask == mfilter->dst_port_mask &&
+ bfilter->flags == mfilter->flags &&
+ bfilter->enables == mfilter->enables) {
+ if (mvnic)
+ *mvnic = vnic;
+ return mfilter;
+ }
+ }
+ }
+ return NULL;
+}
+
+static int
+bnxt_cfg_ntuple_filter(struct bnxt *bp,
+ struct rte_eth_ntuple_filter *nfilter,
+ enum rte_filter_op filter_op)
+{
+ struct bnxt_filter_info *bfilter, *mfilter, *filter1;
+ struct bnxt_vnic_info *vnic, *vnic0, *mvnic;
+ int ret;
+
+ if (nfilter->flags != RTE_5TUPLE_FLAGS) {
+ PMD_DRV_LOG(ERR, "only 5tuple is supported.");
+ return -EINVAL;
+ }
+
+ if (nfilter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG) {
+ PMD_DRV_LOG(ERR, "Ntuple filter: TCP flags not supported\n");
+ return -EINVAL;
+ }
+
+ bfilter = bnxt_get_unused_filter(bp);
+ if (bfilter == NULL) {
+ PMD_DRV_LOG(ERR,
+ "Not enough resources for a new filter.\n");
+ return -ENOMEM;
+ }
+ ret = parse_ntuple_filter(bp, nfilter, bfilter);
+ if (ret < 0)
+ goto free_filter;
+
+ vnic = STAILQ_FIRST(&bp->ff_pool[nfilter->queue]);
+ vnic0 = STAILQ_FIRST(&bp->ff_pool[0]);
+ filter1 = STAILQ_FIRST(&vnic0->filter);
+ if (filter1 == NULL) {
+ ret = -1;
+ goto free_filter;
+ }
+
+ bfilter->dst_id = vnic->fw_vnic_id;
+ bfilter->fw_l2_filter_id = filter1->fw_l2_filter_id;
+ bfilter->enables |=
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID;
+ bfilter->ethertype = 0x800;
+ bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
+
+ mfilter = bnxt_match_ntuple_filter(bp, bfilter, &mvnic);
+
+ if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD &&
+ bfilter->dst_id == mfilter->dst_id) {
+ PMD_DRV_LOG(ERR, "filter exists.\n");
+ ret = -EEXIST;
+ goto free_filter;
+ } else if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD &&
+ bfilter->dst_id != mfilter->dst_id) {
+ mfilter->dst_id = vnic->fw_vnic_id;
+ ret = bnxt_hwrm_set_ntuple_filter(bp, mfilter->dst_id, mfilter);
+ STAILQ_REMOVE(&mvnic->filter, mfilter, bnxt_filter_info, next);
+ STAILQ_INSERT_TAIL(&vnic->filter, mfilter, next);
+ PMD_DRV_LOG(ERR, "filter with matching pattern exists.\n");
+ PMD_DRV_LOG(ERR, " Updated it to the new destination queue\n");
+ goto free_filter;
+ }
+ if (mfilter == NULL && filter_op == RTE_ETH_FILTER_DELETE) {
+ PMD_DRV_LOG(ERR, "filter doesn't exist.");
+ ret = -ENOENT;
+ goto free_filter;
+ }
+
+ if (filter_op == RTE_ETH_FILTER_ADD) {
+ bfilter->filter_type = HWRM_CFA_NTUPLE_FILTER;
+ ret = bnxt_hwrm_set_ntuple_filter(bp, bfilter->dst_id, bfilter);
+ if (ret)
+ goto free_filter;
+ STAILQ_INSERT_TAIL(&vnic->filter, bfilter, next);
+ } else {
+ if (mfilter == NULL) {
+ /* This should not happen. But for Coverity! */
+ ret = -ENOENT;
+ goto free_filter;
+ }
+ ret = bnxt_hwrm_clear_ntuple_filter(bp, mfilter);
+
+ STAILQ_REMOVE(&vnic->filter, mfilter, bnxt_filter_info, next);
+ bnxt_free_filter(bp, mfilter);
+ mfilter->fw_l2_filter_id = -1;
+ bnxt_free_filter(bp, bfilter);
+ bfilter->fw_l2_filter_id = -1;
+ }
+
+ return 0;
+free_filter:
+ bfilter->fw_l2_filter_id = -1;
+ bnxt_free_filter(bp, bfilter);
+ return ret;
+}
+
+static int
+bnxt_ntuple_filter(struct rte_eth_dev *dev,
+ enum rte_filter_op filter_op,
+ void *arg)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ int ret;
+
+ if (filter_op == RTE_ETH_FILTER_NOP)
+ return 0;
+
+ if (arg == NULL) {
+ PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
+ filter_op);
+ return -EINVAL;
+ }
+
+ switch (filter_op) {
+ case RTE_ETH_FILTER_ADD:
+ ret = bnxt_cfg_ntuple_filter(bp,
+ (struct rte_eth_ntuple_filter *)arg,
+ filter_op);
+ break;
+ case RTE_ETH_FILTER_DELETE:
+ ret = bnxt_cfg_ntuple_filter(bp,
+ (struct rte_eth_ntuple_filter *)arg,
+ filter_op);
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int
+bnxt_parse_fdir_filter(struct bnxt *bp,
+ struct rte_eth_fdir_filter *fdir,
+ struct bnxt_filter_info *filter)
+{
+ enum rte_fdir_mode fdir_mode =
+ bp->eth_dev->data->dev_conf.fdir_conf.mode;
+ struct bnxt_vnic_info *vnic0, *vnic;
+ struct bnxt_filter_info *filter1;
+ uint32_t en = 0;
+ int i;
+
+ if (fdir_mode == RTE_FDIR_MODE_PERFECT_TUNNEL)
+ return -EINVAL;
+
+ filter->l2_ovlan = fdir->input.flow_ext.vlan_tci;
+ en |= EM_FLOW_ALLOC_INPUT_EN_OVLAN_VID;
+
+ switch (fdir->input.flow_type) {
+ case RTE_ETH_FLOW_IPV4:
+ case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+ /* FALLTHROUGH */
+ filter->src_ipaddr[0] = fdir->input.flow.ip4_flow.src_ip;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
+ filter->dst_ipaddr[0] = fdir->input.flow.ip4_flow.dst_ip;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
+ filter->ip_protocol = fdir->input.flow.ip4_flow.proto;
+ en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
+ filter->ip_addr_type =
+ NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4;
+ filter->src_ipaddr_mask[0] = 0xffffffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
+ filter->dst_ipaddr_mask[0] = 0xffffffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
+ filter->ethertype = 0x800;
+ filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
+ break;
+ case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
+ filter->src_port = fdir->input.flow.tcp4_flow.src_port;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT;
+ filter->dst_port = fdir->input.flow.tcp4_flow.dst_port;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
+ filter->dst_port_mask = 0xffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
+ filter->src_port_mask = 0xffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
+ filter->src_ipaddr[0] = fdir->input.flow.tcp4_flow.ip.src_ip;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
+ filter->dst_ipaddr[0] = fdir->input.flow.tcp4_flow.ip.dst_ip;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
+ filter->ip_protocol = 6;
+ en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
+ filter->ip_addr_type =
+ NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4;
+ filter->src_ipaddr_mask[0] = 0xffffffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
+ filter->dst_ipaddr_mask[0] = 0xffffffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
+ filter->ethertype = 0x800;
+ filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
+ break;
+ case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
+ filter->src_port = fdir->input.flow.udp4_flow.src_port;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT;
+ filter->dst_port = fdir->input.flow.udp4_flow.dst_port;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
+ filter->dst_port_mask = 0xffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
+ filter->src_port_mask = 0xffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
+ filter->src_ipaddr[0] = fdir->input.flow.udp4_flow.ip.src_ip;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
+ filter->dst_ipaddr[0] = fdir->input.flow.udp4_flow.ip.dst_ip;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
+ filter->ip_protocol = 17;
+ en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
+ filter->ip_addr_type =
+ NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4;
+ filter->src_ipaddr_mask[0] = 0xffffffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
+ filter->dst_ipaddr_mask[0] = 0xffffffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
+ filter->ethertype = 0x800;
+ filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
+ break;
+ case RTE_ETH_FLOW_IPV6:
+ case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+ /* FALLTHROUGH */
+ filter->ip_addr_type =
+ NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6;
+ filter->ip_protocol = fdir->input.flow.ipv6_flow.proto;
+ en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
+ rte_memcpy(filter->src_ipaddr,
+ fdir->input.flow.ipv6_flow.src_ip, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
+ rte_memcpy(filter->dst_ipaddr,
+ fdir->input.flow.ipv6_flow.dst_ip, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
+ memset(filter->dst_ipaddr_mask, 0xff, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
+ memset(filter->src_ipaddr_mask, 0xff, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
+ filter->ethertype = 0x86dd;
+ filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
+ break;
+ case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
+ filter->src_port = fdir->input.flow.tcp6_flow.src_port;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT;
+ filter->dst_port = fdir->input.flow.tcp6_flow.dst_port;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
+ filter->dst_port_mask = 0xffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
+ filter->src_port_mask = 0xffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
+ filter->ip_addr_type =
+ NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6;
+ filter->ip_protocol = fdir->input.flow.tcp6_flow.ip.proto;
+ en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
+ rte_memcpy(filter->src_ipaddr,
+ fdir->input.flow.tcp6_flow.ip.src_ip, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
+ rte_memcpy(filter->dst_ipaddr,
+ fdir->input.flow.tcp6_flow.ip.dst_ip, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
+ memset(filter->dst_ipaddr_mask, 0xff, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
+ memset(filter->src_ipaddr_mask, 0xff, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
+ filter->ethertype = 0x86dd;
+ filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
+ break;
+ case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
+ filter->src_port = fdir->input.flow.udp6_flow.src_port;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT;
+ filter->dst_port = fdir->input.flow.udp6_flow.dst_port;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
+ filter->dst_port_mask = 0xffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
+ filter->src_port_mask = 0xffff;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
+ filter->ip_addr_type =
+ NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6;
+ filter->ip_protocol = fdir->input.flow.udp6_flow.ip.proto;
+ en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
+ rte_memcpy(filter->src_ipaddr,
+ fdir->input.flow.udp6_flow.ip.src_ip, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
+ rte_memcpy(filter->dst_ipaddr,
+ fdir->input.flow.udp6_flow.ip.dst_ip, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
+ memset(filter->dst_ipaddr_mask, 0xff, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
+ memset(filter->src_ipaddr_mask, 0xff, 16);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
+ filter->ethertype = 0x86dd;
+ filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
+ break;
+ case RTE_ETH_FLOW_L2_PAYLOAD:
+ filter->ethertype = fdir->input.flow.l2_flow.ether_type;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
+ break;
+ case RTE_ETH_FLOW_VXLAN:
+ if (fdir->action.behavior == RTE_ETH_FDIR_REJECT)
+ return -EINVAL;
+ filter->vni = fdir->input.flow.tunnel_flow.tunnel_id;
+ filter->tunnel_type =
+ CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN;
+ en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE;
+ break;
+ case RTE_ETH_FLOW_NVGRE:
+ if (fdir->action.behavior == RTE_ETH_FDIR_REJECT)
+ return -EINVAL;
+ filter->vni = fdir->input.flow.tunnel_flow.tunnel_id;
+ filter->tunnel_type =
+ CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE;
+ en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE;
+ break;
+ case RTE_ETH_FLOW_UNKNOWN:
+ case RTE_ETH_FLOW_RAW:
+ case RTE_ETH_FLOW_FRAG_IPV4:
+ case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
+ case RTE_ETH_FLOW_FRAG_IPV6:
+ case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
+ case RTE_ETH_FLOW_IPV6_EX:
+ case RTE_ETH_FLOW_IPV6_TCP_EX:
+ case RTE_ETH_FLOW_IPV6_UDP_EX:
+ case RTE_ETH_FLOW_GENEVE:
+ /* FALLTHROUGH */
+ default:
+ return -EINVAL;
+ }
+
+ vnic0 = STAILQ_FIRST(&bp->ff_pool[0]);
+ vnic = STAILQ_FIRST(&bp->ff_pool[fdir->action.rx_queue]);
+ if (vnic == NULL) {
+ PMD_DRV_LOG(ERR, "Invalid queue %d\n", fdir->action.rx_queue);
+ return -EINVAL;
+ }
+
+
+ if (fdir_mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
+ rte_memcpy(filter->dst_macaddr,
+ fdir->input.flow.mac_vlan_flow.mac_addr.addr_bytes, 6);
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR;
+ }
+
+ if (fdir->action.behavior == RTE_ETH_FDIR_REJECT) {
+ filter->flags = HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP;
+ filter1 = STAILQ_FIRST(&vnic0->filter);
+ //filter1 = bnxt_get_l2_filter(bp, filter, vnic0);
+ } else {
+ filter->dst_id = vnic->fw_vnic_id;
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ if (filter->dst_macaddr[i] == 0x00)
+ filter1 = STAILQ_FIRST(&vnic0->filter);
+ else
+ filter1 = bnxt_get_l2_filter(bp, filter, vnic);
+ }
+
+ if (filter1 == NULL)
+ return -EINVAL;
+
+ en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID;
+ filter->fw_l2_filter_id = filter1->fw_l2_filter_id;
+
+ filter->enables = en;
+
+ return 0;
+}
+
+static struct bnxt_filter_info *
+bnxt_match_fdir(struct bnxt *bp, struct bnxt_filter_info *nf,
+ struct bnxt_vnic_info **mvnic)
+{
+ struct bnxt_filter_info *mf = NULL;
+ int i;
+
+ for (i = bp->nr_vnics - 1; i >= 0; i--) {
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+ STAILQ_FOREACH(mf, &vnic->filter, next) {
+ if (mf->filter_type == nf->filter_type &&
+ mf->flags == nf->flags &&
+ mf->src_port == nf->src_port &&
+ mf->src_port_mask == nf->src_port_mask &&
+ mf->dst_port == nf->dst_port &&
+ mf->dst_port_mask == nf->dst_port_mask &&
+ mf->ip_protocol == nf->ip_protocol &&
+ mf->ip_addr_type == nf->ip_addr_type &&
+ mf->ethertype == nf->ethertype &&
+ mf->vni == nf->vni &&
+ mf->tunnel_type == nf->tunnel_type &&
+ mf->l2_ovlan == nf->l2_ovlan &&
+ mf->l2_ovlan_mask == nf->l2_ovlan_mask &&
+ mf->l2_ivlan == nf->l2_ivlan &&
+ mf->l2_ivlan_mask == nf->l2_ivlan_mask &&
+ !memcmp(mf->l2_addr, nf->l2_addr, ETHER_ADDR_LEN) &&
+ !memcmp(mf->l2_addr_mask, nf->l2_addr_mask,
+ ETHER_ADDR_LEN) &&
+ !memcmp(mf->src_macaddr, nf->src_macaddr,
+ ETHER_ADDR_LEN) &&
+ !memcmp(mf->dst_macaddr, nf->dst_macaddr,
+ ETHER_ADDR_LEN) &&
+ !memcmp(mf->src_ipaddr, nf->src_ipaddr,
+ sizeof(nf->src_ipaddr)) &&
+ !memcmp(mf->src_ipaddr_mask, nf->src_ipaddr_mask,
+ sizeof(nf->src_ipaddr_mask)) &&
+ !memcmp(mf->dst_ipaddr, nf->dst_ipaddr,
+ sizeof(nf->dst_ipaddr)) &&
+ !memcmp(mf->dst_ipaddr_mask, nf->dst_ipaddr_mask,
+ sizeof(nf->dst_ipaddr_mask))) {
+ if (mvnic)
+ *mvnic = vnic;
+ return mf;
+ }
+ }
+ }
+ return NULL;
+}
+
+static int
+bnxt_fdir_filter(struct rte_eth_dev *dev,
+ enum rte_filter_op filter_op,
+ void *arg)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct rte_eth_fdir_filter *fdir = (struct rte_eth_fdir_filter *)arg;
+ struct bnxt_filter_info *filter, *match;
+ struct bnxt_vnic_info *vnic, *mvnic;
+ int ret = 0, i;
+
+ if (filter_op == RTE_ETH_FILTER_NOP)
+ return 0;
+
+ if (arg == NULL && filter_op != RTE_ETH_FILTER_FLUSH)
+ return -EINVAL;
+
+ switch (filter_op) {
+ case RTE_ETH_FILTER_ADD:
+ case RTE_ETH_FILTER_DELETE:
+ /* FALLTHROUGH */
+ filter = bnxt_get_unused_filter(bp);
+ if (filter == NULL) {
+ PMD_DRV_LOG(ERR,
+ "Not enough resources for a new flow.\n");
+ return -ENOMEM;
+ }
+
+ ret = bnxt_parse_fdir_filter(bp, fdir, filter);
+ if (ret != 0)
+ goto free_filter;
+ filter->filter_type = HWRM_CFA_NTUPLE_FILTER;
+
+ if (fdir->action.behavior == RTE_ETH_FDIR_REJECT)
+ vnic = STAILQ_FIRST(&bp->ff_pool[0]);
+ else
+ vnic = STAILQ_FIRST(&bp->ff_pool[fdir->action.rx_queue]);
+
+ match = bnxt_match_fdir(bp, filter, &mvnic);
+ if (match != NULL && filter_op == RTE_ETH_FILTER_ADD) {
+ if (match->dst_id == vnic->fw_vnic_id) {
+ PMD_DRV_LOG(ERR, "Flow already exists.\n");
+ ret = -EEXIST;
+ goto free_filter;
+ } else {
+ match->dst_id = vnic->fw_vnic_id;
+ ret = bnxt_hwrm_set_ntuple_filter(bp,
+ match->dst_id,
+ match);
+ STAILQ_REMOVE(&mvnic->filter, match,
+ bnxt_filter_info, next);
+ STAILQ_INSERT_TAIL(&vnic->filter, match, next);
+ PMD_DRV_LOG(ERR,
+ "Filter with matching pattern exist\n");
+ PMD_DRV_LOG(ERR,
+ "Updated it to new destination q\n");
+ goto free_filter;
+ }
+ }
+ if (match == NULL && filter_op == RTE_ETH_FILTER_DELETE) {
+ PMD_DRV_LOG(ERR, "Flow does not exist.\n");
+ ret = -ENOENT;
+ goto free_filter;
+ }
+
+ if (filter_op == RTE_ETH_FILTER_ADD) {
+ ret = bnxt_hwrm_set_ntuple_filter(bp,
+ filter->dst_id,
+ filter);
+ if (ret)
+ goto free_filter;
+ STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+ } else {
+ ret = bnxt_hwrm_clear_ntuple_filter(bp, match);
+ STAILQ_REMOVE(&vnic->filter, match,
+ bnxt_filter_info, next);
+ bnxt_free_filter(bp, match);
+ filter->fw_l2_filter_id = -1;
+ bnxt_free_filter(bp, filter);
+ }
+ break;
+ case RTE_ETH_FILTER_FLUSH:
+ for (i = bp->nr_vnics - 1; i >= 0; i--) {
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+ STAILQ_FOREACH(filter, &vnic->filter, next) {
+ if (filter->filter_type ==
+ HWRM_CFA_NTUPLE_FILTER) {
+ ret =
+ bnxt_hwrm_clear_ntuple_filter(bp,
+ filter);
+ STAILQ_REMOVE(&vnic->filter, filter,
+ bnxt_filter_info, next);
+ }
+ }
+ }
+ return ret;
+ case RTE_ETH_FILTER_UPDATE:
+ case RTE_ETH_FILTER_STATS:
+ case RTE_ETH_FILTER_INFO:
+ PMD_DRV_LOG(ERR, "operation %u not implemented", filter_op);
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "unknown operation %u", filter_op);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+
+free_filter:
+ filter->fw_l2_filter_id = -1;
+ bnxt_free_filter(bp, filter);
+ return ret;
+}
+
+static int
+bnxt_filter_ctrl_op(struct rte_eth_dev *dev __rte_unused,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg)
+{
+ int ret = 0;
+
+ switch (filter_type) {
+ case RTE_ETH_FILTER_TUNNEL:
+ PMD_DRV_LOG(ERR,
+ "filter type: %d: To be implemented\n", filter_type);
+ break;
+ case RTE_ETH_FILTER_FDIR:
+ ret = bnxt_fdir_filter(dev, filter_op, arg);
+ break;
+ case RTE_ETH_FILTER_NTUPLE:
+ ret = bnxt_ntuple_filter(dev, filter_op, arg);
+ break;
+ case RTE_ETH_FILTER_ETHERTYPE:
+ ret = bnxt_ethertype_filter(dev, filter_op, arg);
+ break;
+ case RTE_ETH_FILTER_GENERIC:
+ if (filter_op != RTE_ETH_FILTER_GET)
+ return -EINVAL;
+ *(const void **)arg = &bnxt_flow_ops;
+ break;
+ default:
+ PMD_DRV_LOG(ERR,
+ "Filter type (%d) not supported", filter_type);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static const uint32_t *
+bnxt_dev_supported_ptypes_get_op(struct rte_eth_dev *dev)
+{
+ static const uint32_t ptypes[] = {
+ RTE_PTYPE_L2_ETHER_VLAN,
+ RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+ RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+ RTE_PTYPE_L4_ICMP,
+ RTE_PTYPE_L4_TCP,
+ RTE_PTYPE_L4_UDP,
+ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+ RTE_PTYPE_INNER_L4_ICMP,
+ RTE_PTYPE_INNER_L4_TCP,
+ RTE_PTYPE_INNER_L4_UDP,
+ RTE_PTYPE_UNKNOWN
+ };
+
+ if (dev->rx_pkt_burst == bnxt_recv_pkts)
+ return ptypes;
+ return NULL;
+}
+
+static int bnxt_map_regs(struct bnxt *bp, uint32_t *reg_arr, int count,
+ int reg_win)
+{
+ uint32_t reg_base = *reg_arr & 0xfffff000;
+ uint32_t win_off;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ if ((reg_arr[i] & 0xfffff000) != reg_base)
+ return -ERANGE;
+ }
+ win_off = BNXT_GRCPF_REG_WINDOW_BASE_OUT + (reg_win - 1) * 4;
+ rte_cpu_to_le_32(rte_write32(reg_base, (uint8_t *)bp->bar0 + win_off));
+ return 0;
+}
+
+static int bnxt_map_ptp_regs(struct bnxt *bp)
+{
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ uint32_t *reg_arr;
+ int rc, i;
+
+ reg_arr = ptp->rx_regs;
+ rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_RX_REGS, 5);
+ if (rc)
+ return rc;
+
+ reg_arr = ptp->tx_regs;
+ rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_TX_REGS, 6);
+ if (rc)
+ return rc;
+
+ for (i = 0; i < BNXT_PTP_RX_REGS; i++)
+ ptp->rx_mapped_regs[i] = 0x5000 + (ptp->rx_regs[i] & 0xfff);
+
+ for (i = 0; i < BNXT_PTP_TX_REGS; i++)
+ ptp->tx_mapped_regs[i] = 0x6000 + (ptp->tx_regs[i] & 0xfff);
+
+ return 0;
+}
+
+static void bnxt_unmap_ptp_regs(struct bnxt *bp)
+{
+ rte_cpu_to_le_32(rte_write32(0, (uint8_t *)bp->bar0 +
+ BNXT_GRCPF_REG_WINDOW_BASE_OUT + 16));
+ rte_cpu_to_le_32(rte_write32(0, (uint8_t *)bp->bar0 +
+ BNXT_GRCPF_REG_WINDOW_BASE_OUT + 20));
+}
+
+static uint64_t bnxt_cc_read(struct bnxt *bp)
+{
+ uint64_t ns;
+
+ ns = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ BNXT_GRCPF_REG_SYNC_TIME));
+ ns |= (uint64_t)(rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ BNXT_GRCPF_REG_SYNC_TIME + 4))) << 32;
+ return ns;
+}
+
+static int bnxt_get_tx_ts(struct bnxt *bp, uint64_t *ts)
+{
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ uint32_t fifo;
+
+ fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO]));
+ if (fifo & BNXT_PTP_TX_FIFO_EMPTY)
+ return -EAGAIN;
+
+ fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO]));
+ *ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ ptp->tx_mapped_regs[BNXT_PTP_TX_TS_L]));
+ *ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ ptp->tx_mapped_regs[BNXT_PTP_TX_TS_H])) << 32;
+
+ return 0;
+}
+
+static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts)
+{
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ struct bnxt_pf_info *pf = &bp->pf;
+ uint16_t port_id;
+ uint32_t fifo;
+
+ if (!ptp)
+ return -ENODEV;
+
+ fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
+ if (!(fifo & BNXT_PTP_RX_FIFO_PENDING))
+ return -EAGAIN;
+
+ port_id = pf->port_id;
+ rte_cpu_to_le_32(rte_write32(1 << port_id, (uint8_t *)bp->bar0 +
+ ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO_ADV]));
+
+ fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
+ if (fifo & BNXT_PTP_RX_FIFO_PENDING) {
+/* bnxt_clr_rx_ts(bp); TBD */
+ return -EBUSY;
+ }
+
+ *ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L]));
+ *ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+ ptp->rx_mapped_regs[BNXT_PTP_RX_TS_H])) << 32;
+
+ return 0;
+}
+
+static int
+bnxt_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
+{
+ uint64_t ns;
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+
+ if (!ptp)
+ return 0;
+
+ ns = rte_timespec_to_ns(ts);
+ /* Set the timecounters to a new value. */
+ ptp->tc.nsec = ns;
+
+ return 0;
+}
+
+static int
+bnxt_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
+{
+ uint64_t ns, systime_cycles;
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+
+ if (!ptp)
+ return 0;
+
+ systime_cycles = bnxt_cc_read(bp);
+ ns = rte_timecounter_update(&ptp->tc, systime_cycles);
+ *ts = rte_ns_to_timespec(ns);
+
+ return 0;
+}
+static int
+bnxt_timesync_enable(struct rte_eth_dev *dev)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ uint32_t shift = 0;
+
+ if (!ptp)
+ return 0;
+
+ ptp->rx_filter = 1;
+ ptp->tx_tstamp_en = 1;
+ ptp->rxctl = BNXT_PTP_MSG_EVENTS;
+
+ if (!bnxt_hwrm_ptp_cfg(bp))
+ bnxt_map_ptp_regs(bp);
+
+ memset(&ptp->tc, 0, sizeof(struct rte_timecounter));
+ memset(&ptp->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
+ memset(&ptp->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
+
+ ptp->tc.cc_mask = BNXT_CYCLECOUNTER_MASK;
+ ptp->tc.cc_shift = shift;
+ ptp->tc.nsec_mask = (1ULL << shift) - 1;
+
+ ptp->rx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK;
+ ptp->rx_tstamp_tc.cc_shift = shift;
+ ptp->rx_tstamp_tc.nsec_mask = (1ULL << shift) - 1;
+
+ ptp->tx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK;
+ ptp->tx_tstamp_tc.cc_shift = shift;
+ ptp->tx_tstamp_tc.nsec_mask = (1ULL << shift) - 1;
+
+ return 0;
+}
+
+static int
+bnxt_timesync_disable(struct rte_eth_dev *dev)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+
+ if (!ptp)
+ return 0;
+
+ ptp->rx_filter = 0;
+ ptp->tx_tstamp_en = 0;
+ ptp->rxctl = 0;
+
+ bnxt_hwrm_ptp_cfg(bp);
+
+ bnxt_unmap_ptp_regs(bp);
+
+ return 0;
+}
+
+static int
+bnxt_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
+ struct timespec *timestamp,
+ uint32_t flags __rte_unused)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ uint64_t rx_tstamp_cycles = 0;
+ uint64_t ns;
+
+ if (!ptp)
+ return 0;
+
+ bnxt_get_rx_ts(bp, &rx_tstamp_cycles);
+ ns = rte_timecounter_update(&ptp->rx_tstamp_tc, rx_tstamp_cycles);
+ *timestamp = rte_ns_to_timespec(ns);
+ return 0;
+}
+
+static int
+bnxt_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
+ struct timespec *timestamp)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ uint64_t tx_tstamp_cycles = 0;
+ uint64_t ns;
+
+ if (!ptp)
+ return 0;
+
+ bnxt_get_tx_ts(bp, &tx_tstamp_cycles);
+ ns = rte_timecounter_update(&ptp->tx_tstamp_tc, tx_tstamp_cycles);
+ *timestamp = rte_ns_to_timespec(ns);
+
+ return 0;
+}
+
+static int
+bnxt_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+
+ if (!ptp)
+ return 0;
+
+ ptp->tc.nsec += delta;
+
+ return 0;
+}
+
+static int
+bnxt_get_eeprom_length_op(struct rte_eth_dev *dev)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ int rc;
+ uint32_t dir_entries;
+ uint32_t entry_length;
+
+ PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x\n",
+ bp->pdev->addr.domain, bp->pdev->addr.bus,
+ bp->pdev->addr.devid, bp->pdev->addr.function);
+
+ rc = bnxt_hwrm_nvm_get_dir_info(bp, &dir_entries, &entry_length);
+ if (rc != 0)
+ return rc;
+
+ return dir_entries * entry_length;
+}
+
+static int
+bnxt_get_eeprom_op(struct rte_eth_dev *dev,
+ struct rte_dev_eeprom_info *in_eeprom)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ uint32_t index;
+ uint32_t offset;
+
+ PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x in_eeprom->offset = %d "
+ "len = %d\n", bp->pdev->addr.domain,
+ bp->pdev->addr.bus, bp->pdev->addr.devid,
+ bp->pdev->addr.function, in_eeprom->offset, in_eeprom->length);
+
+ if (in_eeprom->offset == 0) /* special offset value to get directory */
+ return bnxt_get_nvram_directory(bp, in_eeprom->length,
+ in_eeprom->data);
+
+ index = in_eeprom->offset >> 24;
+ offset = in_eeprom->offset & 0xffffff;
+
+ if (index != 0)
+ return bnxt_hwrm_get_nvram_item(bp, index - 1, offset,
+ in_eeprom->length, in_eeprom->data);
+
+ return 0;
+}
+
+static bool bnxt_dir_type_is_ape_bin_format(uint16_t dir_type)
+{
+ switch (dir_type) {
+ case BNX_DIR_TYPE_CHIMP_PATCH:
+ case BNX_DIR_TYPE_BOOTCODE:
+ case BNX_DIR_TYPE_BOOTCODE_2:
+ case BNX_DIR_TYPE_APE_FW:
+ case BNX_DIR_TYPE_APE_PATCH:
+ case BNX_DIR_TYPE_KONG_FW:
+ case BNX_DIR_TYPE_KONG_PATCH:
+ case BNX_DIR_TYPE_BONO_FW:
+ case BNX_DIR_TYPE_BONO_PATCH:
+ /* FALLTHROUGH */
+ return true;
+ }
+
+ return false;
+}
+
+static bool bnxt_dir_type_is_other_exec_format(uint16_t dir_type)
+{
+ switch (dir_type) {
+ case BNX_DIR_TYPE_AVS:
+ case BNX_DIR_TYPE_EXP_ROM_MBA:
+ case BNX_DIR_TYPE_PCIE:
+ case BNX_DIR_TYPE_TSCF_UCODE:
+ case BNX_DIR_TYPE_EXT_PHY:
+ case BNX_DIR_TYPE_CCM:
+ case BNX_DIR_TYPE_ISCSI_BOOT:
+ case BNX_DIR_TYPE_ISCSI_BOOT_IPV6:
+ case BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6:
+ /* FALLTHROUGH */
+ return true;
+ }
+
+ return false;
+}
+
+static bool bnxt_dir_type_is_executable(uint16_t dir_type)
+{
+ return bnxt_dir_type_is_ape_bin_format(dir_type) ||
+ bnxt_dir_type_is_other_exec_format(dir_type);
+}
+
+static int
+bnxt_set_eeprom_op(struct rte_eth_dev *dev,
+ struct rte_dev_eeprom_info *in_eeprom)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ uint8_t index, dir_op;
+ uint16_t type, ext, ordinal, attr;
+
+ PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x in_eeprom->offset = %d "
+ "len = %d\n", bp->pdev->addr.domain,
+ bp->pdev->addr.bus, bp->pdev->addr.devid,
+ bp->pdev->addr.function, in_eeprom->offset, in_eeprom->length);
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR, "NVM write not supported from a VF\n");
+ return -EINVAL;
+ }
+
+ type = in_eeprom->magic >> 16;
+
+ if (type == 0xffff) { /* special value for directory operations */
+ index = in_eeprom->magic & 0xff;
+ dir_op = in_eeprom->magic >> 8;
+ if (index == 0)
+ return -EINVAL;
+ switch (dir_op) {
+ case 0x0e: /* erase */
+ if (in_eeprom->offset != ~in_eeprom->magic)
+ return -EINVAL;
+ return bnxt_hwrm_erase_nvram_directory(bp, index - 1);
+ default:
+ return -EINVAL;
+ }
+ }
+
+ /* Create or re-write an NVM item: */
+ if (bnxt_dir_type_is_executable(type) == true)
+ return -EOPNOTSUPP;
+ ext = in_eeprom->magic & 0xffff;
+ ordinal = in_eeprom->offset >> 16;
+ attr = in_eeprom->offset & 0xffff;
+
+ return bnxt_hwrm_flash_nvram(bp, type, ordinal, ext, attr,
+ in_eeprom->data, in_eeprom->length);
+ return 0;
+}
+
+/*
+ * Initialization
+ */
+
+static const struct eth_dev_ops bnxt_dev_ops = {
+ .dev_infos_get = bnxt_dev_info_get_op,
+ .dev_close = bnxt_dev_close_op,
+ .dev_configure = bnxt_dev_configure_op,
+ .dev_start = bnxt_dev_start_op,
+ .dev_stop = bnxt_dev_stop_op,
+ .dev_set_link_up = bnxt_dev_set_link_up_op,
+ .dev_set_link_down = bnxt_dev_set_link_down_op,
+ .stats_get = bnxt_stats_get_op,
+ .stats_reset = bnxt_stats_reset_op,
+ .rx_queue_setup = bnxt_rx_queue_setup_op,
+ .rx_queue_release = bnxt_rx_queue_release_op,
+ .tx_queue_setup = bnxt_tx_queue_setup_op,
+ .tx_queue_release = bnxt_tx_queue_release_op,
+ .rx_queue_intr_enable = bnxt_rx_queue_intr_enable_op,
+ .rx_queue_intr_disable = bnxt_rx_queue_intr_disable_op,
+ .reta_update = bnxt_reta_update_op,
+ .reta_query = bnxt_reta_query_op,
+ .rss_hash_update = bnxt_rss_hash_update_op,
+ .rss_hash_conf_get = bnxt_rss_hash_conf_get_op,
+ .link_update = bnxt_link_update_op,
+ .promiscuous_enable = bnxt_promiscuous_enable_op,
+ .promiscuous_disable = bnxt_promiscuous_disable_op,
+ .allmulticast_enable = bnxt_allmulticast_enable_op,
+ .allmulticast_disable = bnxt_allmulticast_disable_op,
+ .mac_addr_add = bnxt_mac_addr_add_op,
+ .mac_addr_remove = bnxt_mac_addr_remove_op,
+ .flow_ctrl_get = bnxt_flow_ctrl_get_op,
+ .flow_ctrl_set = bnxt_flow_ctrl_set_op,
+ .udp_tunnel_port_add = bnxt_udp_tunnel_port_add_op,
+ .udp_tunnel_port_del = bnxt_udp_tunnel_port_del_op,
+ .vlan_filter_set = bnxt_vlan_filter_set_op,
+ .vlan_offload_set = bnxt_vlan_offload_set_op,
+ .vlan_pvid_set = bnxt_vlan_pvid_set_op,
+ .mtu_set = bnxt_mtu_set_op,
+ .mac_addr_set = bnxt_set_default_mac_addr_op,
+ .xstats_get = bnxt_dev_xstats_get_op,
+ .xstats_get_names = bnxt_dev_xstats_get_names_op,
+ .xstats_reset = bnxt_dev_xstats_reset_op,
+ .fw_version_get = bnxt_fw_version_get,
+ .set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
+ .rxq_info_get = bnxt_rxq_info_get_op,
+ .txq_info_get = bnxt_txq_info_get_op,
+ .dev_led_on = bnxt_dev_led_on_op,
+ .dev_led_off = bnxt_dev_led_off_op,
+ .xstats_get_by_id = bnxt_dev_xstats_get_by_id_op,
+ .xstats_get_names_by_id = bnxt_dev_xstats_get_names_by_id_op,
+ .rx_queue_count = bnxt_rx_queue_count_op,
+ .rx_descriptor_status = bnxt_rx_descriptor_status_op,
+ .tx_descriptor_status = bnxt_tx_descriptor_status_op,
+ .rx_queue_start = bnxt_rx_queue_start,
+ .rx_queue_stop = bnxt_rx_queue_stop,
+ .tx_queue_start = bnxt_tx_queue_start,
+ .tx_queue_stop = bnxt_tx_queue_stop,
+ .filter_ctrl = bnxt_filter_ctrl_op,
+ .dev_supported_ptypes_get = bnxt_dev_supported_ptypes_get_op,
+ .get_eeprom_length = bnxt_get_eeprom_length_op,
+ .get_eeprom = bnxt_get_eeprom_op,
+ .set_eeprom = bnxt_set_eeprom_op,
+ .timesync_enable = bnxt_timesync_enable,
+ .timesync_disable = bnxt_timesync_disable,
+ .timesync_read_time = bnxt_timesync_read_time,
+ .timesync_write_time = bnxt_timesync_write_time,
+ .timesync_adjust_time = bnxt_timesync_adjust_time,
+ .timesync_read_rx_timestamp = bnxt_timesync_read_rx_timestamp,
+ .timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp,
+};
+
+static bool bnxt_vf_pciid(uint16_t id)
+{
+ if (id == BROADCOM_DEV_ID_57304_VF ||
+ id == BROADCOM_DEV_ID_57406_VF ||
+ id == BROADCOM_DEV_ID_5731X_VF ||
+ id == BROADCOM_DEV_ID_5741X_VF ||
+ id == BROADCOM_DEV_ID_57414_VF ||
+ id == BROADCOM_DEV_ID_STRATUS_NIC_VF1 ||
+ id == BROADCOM_DEV_ID_STRATUS_NIC_VF2 ||
+ id == BROADCOM_DEV_ID_58802_VF)
+ return true;
+ return false;
+}
+
+bool bnxt_stratus_device(struct bnxt *bp)
+{
+ uint16_t id = bp->pdev->id.device_id;
+
+ if (id == BROADCOM_DEV_ID_STRATUS_NIC ||
+ id == BROADCOM_DEV_ID_STRATUS_NIC_VF1 ||
+ id == BROADCOM_DEV_ID_STRATUS_NIC_VF2)
+ return true;
+ return false;
+}
+
+static int bnxt_init_board(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = eth_dev->data->dev_private;
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+ int rc;
+
+ /* enable device (incl. PCI PM wakeup), and bus-mastering */
+ if (!pci_dev->mem_resource[0].addr) {
+ PMD_DRV_LOG(ERR,
+ "Cannot find PCI device base address, aborting\n");
+ rc = -ENODEV;
+ goto init_err_disable;
+ }
+
+ bp->eth_dev = eth_dev;
+ bp->pdev = pci_dev;
+
+ bp->bar0 = (void *)pci_dev->mem_resource[0].addr;
+ if (!bp->bar0) {
+ PMD_DRV_LOG(ERR, "Cannot map device registers, aborting\n");
+ rc = -ENOMEM;
+ goto init_err_release;
+ }
+
+ if (!pci_dev->mem_resource[2].addr) {
+ PMD_DRV_LOG(ERR,
+ "Cannot find PCI device BAR 2 address, aborting\n");
+ rc = -ENODEV;
+ goto init_err_release;
+ } else {
+ bp->doorbell_base = (void *)pci_dev->mem_resource[2].addr;
+ }
+
+ return 0;
+
+init_err_release:
+ if (bp->bar0)
+ bp->bar0 = NULL;
+ if (bp->doorbell_base)
+ bp->doorbell_base = NULL;
+
+init_err_disable:
+
+ return rc;
+}
+
+
+#define ALLOW_FUNC(x) \
+ { \
+ typeof(x) arg = (x); \
+ bp->pf.vf_req_fwd[((arg) >> 5)] &= \
+ ~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \
+ }
+static int
+bnxt_dev_init(struct rte_eth_dev *eth_dev)
+{
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+ char mz_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz = NULL;
+ static int version_printed;
+ uint32_t total_alloc_len;
+ rte_iova_t mz_phys_addr;
+ struct bnxt *bp;
+ int rc;
+
+ if (version_printed++ == 0)
+ PMD_DRV_LOG(INFO, "%s\n", bnxt_version);
+
+ rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+ bp = eth_dev->data->dev_private;
+
+ bp->dev_stopped = 1;
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ goto skip_init;
+
+ if (bnxt_vf_pciid(pci_dev->id.device_id))
+ bp->flags |= BNXT_FLAG_VF;
+
+ rc = bnxt_init_board(eth_dev);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "Board initialization failed rc: %x\n", rc);
+ goto error;
+ }
+skip_init:
+ eth_dev->dev_ops = &bnxt_dev_ops;
+ eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
+ eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
+ if (pci_dev->id.device_id != BROADCOM_DEV_ID_NS2) {
+ snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+ "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain,
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function, "rx_port_stats");
+ mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+ mz = rte_memzone_lookup(mz_name);
+ total_alloc_len = RTE_CACHE_LINE_ROUNDUP(
+ sizeof(struct rx_port_stats) + 512);
+ if (!mz) {
+ mz = rte_memzone_reserve(mz_name, total_alloc_len,
+ SOCKET_ID_ANY,
+ RTE_MEMZONE_2MB |
+ RTE_MEMZONE_SIZE_HINT_ONLY |
+ RTE_MEMZONE_IOVA_CONTIG);
+ if (mz == NULL)
+ return -ENOMEM;
+ }
+ memset(mz->addr, 0, mz->len);
+ mz_phys_addr = mz->iova;
+ if ((unsigned long)mz->addr == mz_phys_addr) {
+ PMD_DRV_LOG(WARNING,
+ "Memzone physical address same as virtual.\n");
+ PMD_DRV_LOG(WARNING,
+ "Using rte_mem_virt2iova()\n");
+ mz_phys_addr = rte_mem_virt2iova(mz->addr);
+ if (mz_phys_addr == 0) {
+ PMD_DRV_LOG(ERR,
+ "unable to map address to physical memory\n");
+ return -ENOMEM;
+ }
+ }
+
+ bp->rx_mem_zone = (const void *)mz;
+ bp->hw_rx_port_stats = mz->addr;
+ bp->hw_rx_port_stats_map = mz_phys_addr;
+
+ snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+ "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain,
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function, "tx_port_stats");
+ mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+ mz = rte_memzone_lookup(mz_name);
+ total_alloc_len = RTE_CACHE_LINE_ROUNDUP(
+ sizeof(struct tx_port_stats) + 512);
+ if (!mz) {
+ mz = rte_memzone_reserve(mz_name,
+ total_alloc_len,
+ SOCKET_ID_ANY,
+ RTE_MEMZONE_2MB |
+ RTE_MEMZONE_SIZE_HINT_ONLY |
+ RTE_MEMZONE_IOVA_CONTIG);
+ if (mz == NULL)
+ return -ENOMEM;
+ }
+ memset(mz->addr, 0, mz->len);
+ mz_phys_addr = mz->iova;
+ if ((unsigned long)mz->addr == mz_phys_addr) {
+ PMD_DRV_LOG(WARNING,
+ "Memzone physical address same as virtual.\n");
+ PMD_DRV_LOG(WARNING,
+ "Using rte_mem_virt2iova()\n");
+ mz_phys_addr = rte_mem_virt2iova(mz->addr);
+ if (mz_phys_addr == 0) {
+ PMD_DRV_LOG(ERR,
+ "unable to map address to physical memory\n");
+ return -ENOMEM;
+ }
+ }
+
+ bp->tx_mem_zone = (const void *)mz;
+ bp->hw_tx_port_stats = mz->addr;
+ bp->hw_tx_port_stats_map = mz_phys_addr;
+
+ bp->flags |= BNXT_FLAG_PORT_STATS;
+ }
+
+ rc = bnxt_alloc_hwrm_resources(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "hwrm resource allocation failure rc: %x\n", rc);
+ goto error_free;
+ }
+ rc = bnxt_hwrm_ver_get(bp);
+ if (rc)
+ goto error_free;
+ rc = bnxt_hwrm_queue_qportcfg(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "hwrm queue qportcfg failed\n");
+ goto error_free;
+ }
+
+ rc = bnxt_hwrm_func_qcfg(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "hwrm func qcfg failed\n");
+ goto error_free;
+ }
+
+ /* Get the MAX capabilities for this function */
+ rc = bnxt_hwrm_func_qcaps(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "hwrm query capability failure rc: %x\n", rc);
+ goto error_free;
+ }
+ if (bp->max_tx_rings == 0) {
+ PMD_DRV_LOG(ERR, "No TX rings available!\n");
+ rc = -EBUSY;
+ goto error_free;
+ }
+ eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl",
+ ETHER_ADDR_LEN * bp->max_l2_ctx, 0);
+ if (eth_dev->data->mac_addrs == NULL) {
+ PMD_DRV_LOG(ERR,
+ "Failed to alloc %u bytes needed to store MAC addr tbl",
+ ETHER_ADDR_LEN * bp->max_l2_ctx);
+ rc = -ENOMEM;
+ goto error_free;
+ }
+
+ if (bnxt_check_zero_bytes(bp->dflt_mac_addr, ETHER_ADDR_LEN)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+ bp->dflt_mac_addr[0], bp->dflt_mac_addr[1],
+ bp->dflt_mac_addr[2], bp->dflt_mac_addr[3],
+ bp->dflt_mac_addr[4], bp->dflt_mac_addr[5]);
+ rc = -EINVAL;
+ goto error_free;
+ }
+ /* Copy the permanent MAC from the qcap response address now. */
+ memcpy(bp->mac_addr, bp->dflt_mac_addr, sizeof(bp->mac_addr));
+ memcpy(&eth_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+
+ if (bp->max_ring_grps < bp->rx_cp_nr_rings) {
+ /* 1 ring is for default completion ring */
+ PMD_DRV_LOG(ERR, "Insufficient resource: Ring Group\n");
+ rc = -ENOSPC;
+ goto error_free;
+ }
+
+ bp->grp_info = rte_zmalloc("bnxt_grp_info",
+ sizeof(*bp->grp_info) * bp->max_ring_grps, 0);
+ if (!bp->grp_info) {
+ PMD_DRV_LOG(ERR,
+ "Failed to alloc %zu bytes to store group info table\n",
+ sizeof(*bp->grp_info) * bp->max_ring_grps);
+ rc = -ENOMEM;
+ goto error_free;
+ }
+
+ /* Forward all requests if firmware is new enough */
+ if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) &&
+ (bp->fw_ver < ((20 << 24) | (7 << 16)))) ||
+ ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) {
+ memset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd));
+ } else {
+ PMD_DRV_LOG(WARNING,
+ "Firmware too old for VF mailbox functionality\n");
+ memset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd));
+ }
+
+ /*
+ * The following are used for driver cleanup. If we disallow these,
+ * VF drivers can't clean up cleanly.
+ */
+ ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR);
+ ALLOW_FUNC(HWRM_VNIC_FREE);
+ ALLOW_FUNC(HWRM_RING_FREE);
+ ALLOW_FUNC(HWRM_RING_GRP_FREE);
+ ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE);
+ ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE);
+ ALLOW_FUNC(HWRM_STAT_CTX_FREE);
+ ALLOW_FUNC(HWRM_PORT_PHY_QCFG);
+ ALLOW_FUNC(HWRM_VNIC_TPA_CFG);
+ rc = bnxt_hwrm_func_driver_register(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "Failed to register driver");
+ rc = -EBUSY;
+ goto error_free;
+ }
+
+ PMD_DRV_LOG(INFO,
+ DRV_MODULE_NAME " found at mem %" PRIx64 ", node addr %pM\n",
+ pci_dev->mem_resource[0].phys_addr,
+ pci_dev->mem_resource[0].addr);
+
+ rc = bnxt_hwrm_func_reset(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "hwrm chip reset failure rc: %x\n", rc);
+ rc = -EIO;
+ goto error_free;
+ }
+
+ if (BNXT_PF(bp)) {
+ //if (bp->pf.active_vfs) {
+ // TODO: Deallocate VF resources?
+ //}
+ if (bp->pdev->max_vfs) {
+ rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "Failed to allocate VFs\n");
+ goto error_free;
+ }
+ } else {
+ rc = bnxt_hwrm_allocate_pf_only(bp);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "Failed to allocate PF resources\n");
+ goto error_free;
+ }
+ }
+ }
+
+ bnxt_hwrm_port_led_qcaps(bp);
+
+ rc = bnxt_setup_int(bp);
+ if (rc)
+ goto error_free;
+
+ rc = bnxt_alloc_mem(bp);
+ if (rc)
+ goto error_free_int;
+
+ rc = bnxt_request_int(bp);
+ if (rc)
+ goto error_free_int;
+
+ bnxt_enable_int(bp);
+ bnxt_init_nic(bp);
+
+ return 0;
+
+error_free_int:
+ bnxt_disable_int(bp);
+ bnxt_hwrm_func_buf_unrgtr(bp);
+ bnxt_free_int(bp);
+ bnxt_free_mem(bp);
+error_free:
+ bnxt_dev_uninit(eth_dev);
+error:
+ return rc;
+}
+
+static int
+bnxt_dev_uninit(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = eth_dev->data->dev_private;
+ int rc;
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ PMD_DRV_LOG(DEBUG, "Calling Device uninit\n");
+ bnxt_disable_int(bp);
+ bnxt_free_int(bp);
+ bnxt_free_mem(bp);
+ if (eth_dev->data->mac_addrs != NULL) {
+ rte_free(eth_dev->data->mac_addrs);
+ eth_dev->data->mac_addrs = NULL;
+ }
+ if (bp->grp_info != NULL) {
+ rte_free(bp->grp_info);
+ bp->grp_info = NULL;
+ }
+ rc = bnxt_hwrm_func_driver_unregister(bp, 0);
+ bnxt_free_hwrm_resources(bp);
+
+ if (bp->tx_mem_zone) {
+ rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone);
+ bp->tx_mem_zone = NULL;
+ }
+
+ if (bp->rx_mem_zone) {
+ rte_memzone_free((const struct rte_memzone *)bp->rx_mem_zone);
+ bp->rx_mem_zone = NULL;
+ }
+
+ if (bp->dev_stopped == 0)
+ bnxt_dev_close_op(eth_dev);
+ if (bp->pf.vf_info)
+ rte_free(bp->pf.vf_info);
+ eth_dev->dev_ops = NULL;
+ eth_dev->rx_pkt_burst = NULL;
+ eth_dev->tx_pkt_burst = NULL;
+
+ return rc;
+}
+
+static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct bnxt),
+ bnxt_dev_init);
+}
+
+static int bnxt_pci_remove(struct rte_pci_device *pci_dev)
+{
+ return rte_eth_dev_pci_generic_remove(pci_dev, bnxt_dev_uninit);
+}
+
+static struct rte_pci_driver bnxt_rte_pmd = {
+ .id_table = bnxt_pci_id_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING |
+ RTE_PCI_DRV_INTR_LSC,
+ .probe = bnxt_pci_probe,
+ .remove = bnxt_pci_remove,
+};
+
+static bool
+is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv)
+{
+ if (strcmp(dev->device->driver->name, drv->driver.name))
+ return false;
+
+ return true;
+}
+
+bool is_bnxt_supported(struct rte_eth_dev *dev)
+{
+ return is_device_supported(dev, &bnxt_rte_pmd);
+}
+
+RTE_INIT(bnxt_init_log)
+{
+ bnxt_logtype_driver = rte_log_register("pmd.bnxt.driver");
+ if (bnxt_logtype_driver >= 0)
+ rte_log_set_level(bnxt_logtype_driver, RTE_LOG_INFO);
+}
+
+RTE_PMD_REGISTER_PCI(net_bnxt, bnxt_rte_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(net_bnxt, bnxt_pci_id_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_bnxt, "* igb_uio | uio_pci_generic | vfio-pci");
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_filter.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_filter.c
new file mode 100644
index 00000000..1038941e
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_filter.c
@@ -0,0 +1,195 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <sys/queue.h>
+
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_flow.h>
+#include <rte_flow_driver.h>
+#include <rte_tailq.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_vnic.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * Filter Functions
+ */
+
+struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp)
+{
+ struct bnxt_filter_info *filter;
+
+ /* Find the 1st unused filter from the free_filter_list pool*/
+ filter = STAILQ_FIRST(&bp->free_filter_list);
+ if (!filter) {
+ PMD_DRV_LOG(ERR, "No more free filter resources\n");
+ return NULL;
+ }
+ STAILQ_REMOVE_HEAD(&bp->free_filter_list, next);
+
+ /* Default to L2 MAC Addr filter */
+ filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
+ filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
+ memcpy(filter->l2_addr, bp->eth_dev->data->mac_addrs->addr_bytes,
+ ETHER_ADDR_LEN);
+ memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+ return filter;
+}
+
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf)
+{
+ struct bnxt_filter_info *filter;
+
+ filter = rte_zmalloc("bnxt_vf_filter_info", sizeof(*filter), 0);
+ if (!filter) {
+ PMD_DRV_LOG(ERR, "Failed to alloc memory for VF %hu filters\n",
+ vf);
+ return NULL;
+ }
+
+ filter->fw_l2_filter_id = UINT64_MAX;
+ STAILQ_INSERT_TAIL(&bp->pf.vf_info[vf].filter, filter, next);
+ return filter;
+}
+
+void bnxt_init_filters(struct bnxt *bp)
+{
+ struct bnxt_filter_info *filter;
+ int i, max_filters;
+
+ max_filters = bp->max_l2_ctx;
+ STAILQ_INIT(&bp->free_filter_list);
+ for (i = 0; i < max_filters; i++) {
+ filter = &bp->filter_info[i];
+ filter->fw_l2_filter_id = UINT64_MAX;
+ filter->fw_em_filter_id = UINT64_MAX;
+ filter->fw_ntuple_filter_id = UINT64_MAX;
+ STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);
+ }
+}
+
+void bnxt_free_all_filters(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+ struct bnxt_filter_info *filter, *temp_filter;
+ int i;
+
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ filter = STAILQ_FIRST(&vnic->filter);
+ while (filter) {
+ temp_filter = STAILQ_NEXT(filter, next);
+ STAILQ_REMOVE(&vnic->filter, filter,
+ bnxt_filter_info, next);
+ STAILQ_INSERT_TAIL(&bp->free_filter_list,
+ filter, next);
+ filter = temp_filter;
+ }
+ STAILQ_INIT(&vnic->filter);
+ }
+ }
+
+ for (i = 0; i < bp->pf.max_vfs; i++) {
+ STAILQ_FOREACH(filter, &bp->pf.vf_info[i].filter, next) {
+ bnxt_hwrm_clear_l2_filter(bp, filter);
+ }
+ }
+}
+
+void bnxt_free_filter_mem(struct bnxt *bp)
+{
+ struct bnxt_filter_info *filter;
+ uint16_t max_filters, i;
+ int rc = 0;
+
+ if (bp->filter_info == NULL)
+ return;
+
+ /* Ensure that all filters are freed */
+ max_filters = bp->max_l2_ctx;
+ for (i = 0; i < max_filters; i++) {
+ filter = &bp->filter_info[i];
+ if (filter->fw_l2_filter_id != ((uint64_t)-1) &&
+ filter->filter_type == HWRM_CFA_L2_FILTER) {
+ PMD_DRV_LOG(ERR, "L2 filter is not free\n");
+ /* Call HWRM to try to free filter again */
+ rc = bnxt_hwrm_clear_l2_filter(bp, filter);
+ if (rc)
+ PMD_DRV_LOG(ERR,
+ "Cannot free L2 filter: %d\n",
+ rc);
+ }
+ filter->fw_l2_filter_id = UINT64_MAX;
+
+ if (filter->fw_ntuple_filter_id != ((uint64_t)-1) &&
+ filter->filter_type == HWRM_CFA_NTUPLE_FILTER) {
+ PMD_DRV_LOG(ERR, "NTUPLE filter is not free\n");
+ /* Call HWRM to try to free filter again */
+ rc = bnxt_hwrm_clear_ntuple_filter(bp, filter);
+ if (rc)
+ PMD_DRV_LOG(ERR,
+ "Cannot free NTUPLE filter: %d\n",
+ rc);
+ }
+ filter->fw_ntuple_filter_id = UINT64_MAX;
+ }
+ STAILQ_INIT(&bp->free_filter_list);
+
+ rte_free(bp->filter_info);
+ bp->filter_info = NULL;
+
+ for (i = 0; i < bp->pf.max_vfs; i++) {
+ STAILQ_FOREACH(filter, &bp->pf.vf_info[i].filter, next) {
+ rte_free(filter);
+ STAILQ_REMOVE(&bp->pf.vf_info[i].filter, filter,
+ bnxt_filter_info, next);
+ }
+ }
+}
+
+int bnxt_alloc_filter_mem(struct bnxt *bp)
+{
+ struct bnxt_filter_info *filter_mem;
+ uint16_t max_filters;
+
+ max_filters = bp->max_l2_ctx;
+ /* Allocate memory for VNIC pool and filter pool */
+ filter_mem = rte_zmalloc("bnxt_filter_info",
+ max_filters * sizeof(struct bnxt_filter_info),
+ 0);
+ if (filter_mem == NULL) {
+ PMD_DRV_LOG(ERR, "Failed to alloc memory for %d filters",
+ max_filters);
+ return -ENOMEM;
+ }
+ bp->filter_info = filter_mem;
+ return 0;
+}
+
+struct bnxt_filter_info *bnxt_get_unused_filter(struct bnxt *bp)
+{
+ struct bnxt_filter_info *filter;
+
+ /* Find the 1st unused filter from the free_filter_list pool*/
+ filter = STAILQ_FIRST(&bp->free_filter_list);
+ if (!filter) {
+ PMD_DRV_LOG(ERR, "No more free filter resources\n");
+ return NULL;
+ }
+ STAILQ_REMOVE_HEAD(&bp->free_filter_list, next);
+
+ return filter;
+}
+
+void bnxt_free_filter(struct bnxt *bp, struct bnxt_filter_info *filter)
+{
+ STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_filter.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_filter.h
new file mode 100644
index 00000000..a1ecfb19
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_filter.h
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_FILTER_H_
+#define _BNXT_FILTER_H_
+
+#include <rte_ether.h>
+
+struct bnxt;
+struct bnxt_filter_info {
+ STAILQ_ENTRY(bnxt_filter_info) next;
+ uint64_t fw_l2_filter_id;
+ uint64_t fw_em_filter_id;
+ uint64_t fw_ntuple_filter_id;
+#define INVALID_MAC_INDEX ((uint16_t)-1)
+ uint16_t mac_index;
+#define HWRM_CFA_L2_FILTER 0
+#define HWRM_CFA_EM_FILTER 1
+#define HWRM_CFA_NTUPLE_FILTER 2
+ uint8_t filter_type; //L2 or EM or NTUPLE filter
+ uint32_t dst_id;
+
+ /* Filter Characteristics */
+ uint32_t flags;
+ uint32_t enables;
+ uint8_t l2_addr[ETHER_ADDR_LEN];
+ uint8_t l2_addr_mask[ETHER_ADDR_LEN];
+ uint16_t l2_ovlan;
+ uint16_t l2_ovlan_mask;
+ uint16_t l2_ivlan;
+ uint16_t l2_ivlan_mask;
+ uint8_t t_l2_addr[ETHER_ADDR_LEN];
+ uint8_t t_l2_addr_mask[ETHER_ADDR_LEN];
+ uint16_t t_l2_ovlan;
+ uint16_t t_l2_ovlan_mask;
+ uint16_t t_l2_ivlan;
+ uint16_t t_l2_ivlan_mask;
+ uint8_t tunnel_type;
+ uint16_t mirror_vnic_id;
+ uint32_t vni;
+ uint8_t pri_hint;
+ uint64_t l2_filter_id_hint;
+ uint32_t src_id;
+ uint8_t src_type;
+ uint8_t src_macaddr[6];
+ uint8_t dst_macaddr[6];
+ uint32_t dst_ipaddr[4];
+ uint32_t dst_ipaddr_mask[4];
+ uint32_t src_ipaddr[4];
+ uint32_t src_ipaddr_mask[4];
+ uint16_t dst_port;
+ uint16_t dst_port_mask;
+ uint16_t src_port;
+ uint16_t src_port_mask;
+ uint16_t ip_protocol;
+ uint16_t ip_addr_type;
+ uint16_t ethertype;
+};
+
+struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf);
+void bnxt_init_filters(struct bnxt *bp);
+void bnxt_free_all_filters(struct bnxt *bp);
+void bnxt_free_filter_mem(struct bnxt *bp);
+int bnxt_alloc_filter_mem(struct bnxt *bp);
+struct bnxt_filter_info *bnxt_get_unused_filter(struct bnxt *bp);
+void bnxt_free_filter(struct bnxt *bp, struct bnxt_filter_info *filter);
+struct bnxt_filter_info *bnxt_get_l2_filter(struct bnxt *bp,
+ struct bnxt_filter_info *nf, struct bnxt_vnic_info *vnic);
+
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_MACADDR \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_MACADDR
+#define EM_FLOW_ALLOC_INPUT_EN_SRC_MACADDR \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_SRC_MACADDR
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_MACADDR
+#define EM_FLOW_ALLOC_INPUT_EN_DST_MACADDR \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_MACADDR
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_ETHERTYPE
+#define EM_FLOW_ALLOC_INPUT_EN_ETHERTYPE \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_ETHERTYPE
+#define EM_FLOW_ALLOC_INPUT_EN_OVLAN_VID \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_OVLAN_VID
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_IPADDR
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_IPADDR_MASK
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_IPADDR
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_IPADDR_MASK
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_PORT
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_PORT_MASK
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_PORT
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_PORT_MASK
+#define NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_IP_PROTOCOL
+#define EM_FLOW_ALLOC_INPUT_EN_SRC_IPADDR \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_SRC_IPADDR
+#define EM_FLOW_ALLOC_INPUT_EN_DST_IPADDR \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_IPADDR
+#define EM_FLOW_ALLOC_INPUT_EN_SRC_PORT \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_SRC_PORT
+#define EM_FLOW_ALLOC_INPUT_EN_DST_PORT \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_PORT
+#define EM_FLOW_ALLOC_INPUT_EN_IP_PROTO \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_IP_PROTOCOL
+#define EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV6 \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV6
+#define NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6 \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV6
+#define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN
+#define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE
+#define L2_FILTER_ALLOC_INPUT_EN_L2_ADDR_MASK \
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK
+#define NTUPLE_FLTR_ALLOC_INPUT_IP_PROTOCOL_UDP \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_PROTOCOL_UDP
+#define NTUPLE_FLTR_ALLOC_INPUT_IP_PROTOCOL_TCP \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_PROTOCOL_TCP
+#define NTUPLE_FLTR_ALLOC_INPUT_IP_PROTOCOL_UNKNOWN \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_PROTOCOL_UNKNOWN
+#define NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4 \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV4
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_MIRROR_VNIC_ID \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID
+#define NTUPLE_FLTR_ALLOC_INPUT_EN_MIRROR_VNIC_ID \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_flow.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_flow.c
new file mode 100644
index 00000000..ac765674
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_flow.c
@@ -0,0 +1,1171 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <sys/queue.h>
+
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_flow.h>
+#include <rte_flow_driver.h>
+#include <rte_tailq.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_vnic.h"
+#include "bnxt_util.h"
+#include "hsi_struct_def_dpdk.h"
+
+static int
+bnxt_flow_args_validate(const struct rte_flow_attr *attr,
+ const struct rte_flow_item pattern[],
+ const struct rte_flow_action actions[],
+ struct rte_flow_error *error)
+{
+ if (!pattern) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM_NUM,
+ NULL,
+ "NULL pattern.");
+ return -rte_errno;
+ }
+
+ if (!actions) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_NUM,
+ NULL,
+ "NULL action.");
+ return -rte_errno;
+ }
+
+ if (!attr) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL,
+ "NULL attribute.");
+ return -rte_errno;
+ }
+
+ return 0;
+}
+
+static const struct rte_flow_item *
+bnxt_flow_non_void_item(const struct rte_flow_item *cur)
+{
+ while (1) {
+ if (cur->type != RTE_FLOW_ITEM_TYPE_VOID)
+ return cur;
+ cur++;
+ }
+}
+
+static const struct rte_flow_action *
+bnxt_flow_non_void_action(const struct rte_flow_action *cur)
+{
+ while (1) {
+ if (cur->type != RTE_FLOW_ACTION_TYPE_VOID)
+ return cur;
+ cur++;
+ }
+}
+
+static int
+bnxt_filter_type_check(const struct rte_flow_item pattern[],
+ struct rte_flow_error *error __rte_unused)
+{
+ const struct rte_flow_item *item =
+ bnxt_flow_non_void_item(pattern);
+ int use_ntuple = 1;
+
+ while (item->type != RTE_FLOW_ITEM_TYPE_END) {
+ switch (item->type) {
+ case RTE_FLOW_ITEM_TYPE_ETH:
+ use_ntuple = 1;
+ break;
+ case RTE_FLOW_ITEM_TYPE_VLAN:
+ use_ntuple = 0;
+ break;
+ case RTE_FLOW_ITEM_TYPE_IPV4:
+ case RTE_FLOW_ITEM_TYPE_IPV6:
+ case RTE_FLOW_ITEM_TYPE_TCP:
+ case RTE_FLOW_ITEM_TYPE_UDP:
+ /* FALLTHROUGH */
+ /* need ntuple match, reset exact match */
+ if (!use_ntuple) {
+ PMD_DRV_LOG(ERR,
+ "VLAN flow cannot use NTUPLE filter\n");
+ rte_flow_error_set
+ (error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Cannot use VLAN with NTUPLE");
+ return -rte_errno;
+ }
+ use_ntuple |= 1;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Unknown Flow type\n");
+ use_ntuple |= 1;
+ }
+ item++;
+ }
+ return use_ntuple;
+}
+
+static int
+bnxt_validate_and_parse_flow_type(struct bnxt *bp,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item pattern[],
+ struct rte_flow_error *error,
+ struct bnxt_filter_info *filter)
+{
+ const struct rte_flow_item *item = bnxt_flow_non_void_item(pattern);
+ const struct rte_flow_item_vlan *vlan_spec, *vlan_mask;
+ const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_mask;
+ const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
+ const struct rte_flow_item_tcp *tcp_spec, *tcp_mask;
+ const struct rte_flow_item_udp *udp_spec, *udp_mask;
+ const struct rte_flow_item_eth *eth_spec, *eth_mask;
+ const struct rte_flow_item_nvgre *nvgre_spec;
+ const struct rte_flow_item_nvgre *nvgre_mask;
+ const struct rte_flow_item_vxlan *vxlan_spec;
+ const struct rte_flow_item_vxlan *vxlan_mask;
+ uint8_t vni_mask[] = {0xFF, 0xFF, 0xFF};
+ uint8_t tni_mask[] = {0xFF, 0xFF, 0xFF};
+ const struct rte_flow_item_vf *vf_spec;
+ uint32_t tenant_id_be = 0;
+ bool vni_masked = 0;
+ bool tni_masked = 0;
+ uint32_t vf = 0;
+ int use_ntuple;
+ uint32_t en = 0;
+ uint32_t en_ethertype;
+ int dflt_vnic;
+
+ use_ntuple = bnxt_filter_type_check(pattern, error);
+ PMD_DRV_LOG(DEBUG, "Use NTUPLE %d\n", use_ntuple);
+ if (use_ntuple < 0)
+ return use_ntuple;
+
+ filter->filter_type = use_ntuple ?
+ HWRM_CFA_NTUPLE_FILTER : HWRM_CFA_EM_FILTER;
+ en_ethertype = use_ntuple ?
+ NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE :
+ EM_FLOW_ALLOC_INPUT_EN_ETHERTYPE;
+
+ while (item->type != RTE_FLOW_ITEM_TYPE_END) {
+ if (item->last) {
+ /* last or range is NOT supported as match criteria */
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "No support for range");
+ return -rte_errno;
+ }
+
+ if (!item->spec || !item->mask) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "spec/mask is NULL");
+ return -rte_errno;
+ }
+
+ switch (item->type) {
+ case RTE_FLOW_ITEM_TYPE_ETH:
+ eth_spec = item->spec;
+ eth_mask = item->mask;
+
+ /* Source MAC address mask cannot be partially set.
+ * Should be All 0's or all 1's.
+ * Destination MAC address mask must not be partially
+ * set. Should be all 1's or all 0's.
+ */
+ if ((!is_zero_ether_addr(&eth_mask->src) &&
+ !is_broadcast_ether_addr(&eth_mask->src)) ||
+ (!is_zero_ether_addr(&eth_mask->dst) &&
+ !is_broadcast_ether_addr(&eth_mask->dst))) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "MAC_addr mask not valid");
+ return -rte_errno;
+ }
+
+ /* Mask is not allowed. Only exact matches are */
+ if (eth_mask->type &&
+ eth_mask->type != RTE_BE16(0xffff)) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "ethertype mask not valid");
+ return -rte_errno;
+ }
+
+ if (is_broadcast_ether_addr(&eth_mask->dst)) {
+ rte_memcpy(filter->dst_macaddr,
+ &eth_spec->dst, 6);
+ en |= use_ntuple ?
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR :
+ EM_FLOW_ALLOC_INPUT_EN_DST_MACADDR;
+ }
+
+ if (is_broadcast_ether_addr(&eth_mask->src)) {
+ rte_memcpy(filter->src_macaddr,
+ &eth_spec->src, 6);
+ en |= use_ntuple ?
+ NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_MACADDR :
+ EM_FLOW_ALLOC_INPUT_EN_SRC_MACADDR;
+ } /*
+ * else {
+ * PMD_DRV_LOG(ERR, "Handle this condition\n");
+ * }
+ */
+ if (eth_mask->type) {
+ filter->ethertype =
+ rte_be_to_cpu_16(eth_spec->type);
+ en |= en_ethertype;
+ }
+
+ break;
+ case RTE_FLOW_ITEM_TYPE_VLAN:
+ vlan_spec = item->spec;
+ vlan_mask = item->mask;
+ if (en & en_ethertype) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "VLAN TPID matching is not"
+ " supported");
+ return -rte_errno;
+ }
+ if (vlan_mask->tci &&
+ vlan_mask->tci == RTE_BE16(0x0fff)) {
+ /* Only the VLAN ID can be matched. */
+ filter->l2_ovlan =
+ rte_be_to_cpu_16(vlan_spec->tci &
+ RTE_BE16(0x0fff));
+ en |= EM_FLOW_ALLOC_INPUT_EN_OVLAN_VID;
+ } else {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "VLAN mask is invalid");
+ return -rte_errno;
+ }
+ if (vlan_mask->inner_type &&
+ vlan_mask->inner_type != RTE_BE16(0xffff)) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "inner ethertype mask not"
+ " valid");
+ return -rte_errno;
+ }
+ if (vlan_mask->inner_type) {
+ filter->ethertype =
+ rte_be_to_cpu_16(vlan_spec->inner_type);
+ en |= en_ethertype;
+ }
+
+ break;
+ case RTE_FLOW_ITEM_TYPE_IPV4:
+ /* If mask is not involved, we could use EM filters. */
+ ipv4_spec = item->spec;
+ ipv4_mask = item->mask;
+ /* Only IP DST and SRC fields are maskable. */
+ if (ipv4_mask->hdr.version_ihl ||
+ ipv4_mask->hdr.type_of_service ||
+ ipv4_mask->hdr.total_length ||
+ ipv4_mask->hdr.packet_id ||
+ ipv4_mask->hdr.fragment_offset ||
+ ipv4_mask->hdr.time_to_live ||
+ ipv4_mask->hdr.next_proto_id ||
+ ipv4_mask->hdr.hdr_checksum) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid IPv4 mask.");
+ return -rte_errno;
+ }
+
+ filter->dst_ipaddr[0] = ipv4_spec->hdr.dst_addr;
+ filter->src_ipaddr[0] = ipv4_spec->hdr.src_addr;
+
+ if (use_ntuple)
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR |
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
+ else
+ en |= EM_FLOW_ALLOC_INPUT_EN_SRC_IPADDR |
+ EM_FLOW_ALLOC_INPUT_EN_DST_IPADDR;
+
+ if (ipv4_mask->hdr.src_addr) {
+ filter->src_ipaddr_mask[0] =
+ ipv4_mask->hdr.src_addr;
+ en |= !use_ntuple ? 0 :
+ NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
+ }
+
+ if (ipv4_mask->hdr.dst_addr) {
+ filter->dst_ipaddr_mask[0] =
+ ipv4_mask->hdr.dst_addr;
+ en |= !use_ntuple ? 0 :
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
+ }
+
+ filter->ip_addr_type = use_ntuple ?
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV4 :
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV4;
+
+ if (ipv4_spec->hdr.next_proto_id) {
+ filter->ip_protocol =
+ ipv4_spec->hdr.next_proto_id;
+ if (use_ntuple)
+ en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
+ else
+ en |= EM_FLOW_ALLOC_INPUT_EN_IP_PROTO;
+ }
+ break;
+ case RTE_FLOW_ITEM_TYPE_IPV6:
+ ipv6_spec = item->spec;
+ ipv6_mask = item->mask;
+
+ /* Only IP DST and SRC fields are maskable. */
+ if (ipv6_mask->hdr.vtc_flow ||
+ ipv6_mask->hdr.payload_len ||
+ ipv6_mask->hdr.proto ||
+ ipv6_mask->hdr.hop_limits) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid IPv6 mask.");
+ return -rte_errno;
+ }
+
+ if (use_ntuple)
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR |
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
+ else
+ en |= EM_FLOW_ALLOC_INPUT_EN_SRC_IPADDR |
+ EM_FLOW_ALLOC_INPUT_EN_DST_IPADDR;
+
+ rte_memcpy(filter->src_ipaddr,
+ ipv6_spec->hdr.src_addr, 16);
+ rte_memcpy(filter->dst_ipaddr,
+ ipv6_spec->hdr.dst_addr, 16);
+
+ if (!bnxt_check_zero_bytes(ipv6_mask->hdr.src_addr,
+ 16)) {
+ rte_memcpy(filter->src_ipaddr_mask,
+ ipv6_mask->hdr.src_addr, 16);
+ en |= !use_ntuple ? 0 :
+ NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
+ }
+
+ if (!bnxt_check_zero_bytes(ipv6_mask->hdr.dst_addr,
+ 16)) {
+ rte_memcpy(filter->dst_ipaddr_mask,
+ ipv6_mask->hdr.dst_addr, 16);
+ en |= !use_ntuple ? 0 :
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
+ }
+
+ filter->ip_addr_type = use_ntuple ?
+ NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6 :
+ EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV6;
+ break;
+ case RTE_FLOW_ITEM_TYPE_TCP:
+ tcp_spec = item->spec;
+ tcp_mask = item->mask;
+
+ /* Check TCP mask. Only DST & SRC ports are maskable */
+ if (tcp_mask->hdr.sent_seq ||
+ tcp_mask->hdr.recv_ack ||
+ tcp_mask->hdr.data_off ||
+ tcp_mask->hdr.tcp_flags ||
+ tcp_mask->hdr.rx_win ||
+ tcp_mask->hdr.cksum ||
+ tcp_mask->hdr.tcp_urp) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid TCP mask");
+ return -rte_errno;
+ }
+
+ filter->src_port = tcp_spec->hdr.src_port;
+ filter->dst_port = tcp_spec->hdr.dst_port;
+
+ if (use_ntuple)
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT |
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
+ else
+ en |= EM_FLOW_ALLOC_INPUT_EN_SRC_PORT |
+ EM_FLOW_ALLOC_INPUT_EN_DST_PORT;
+
+ if (tcp_mask->hdr.dst_port) {
+ filter->dst_port_mask = tcp_mask->hdr.dst_port;
+ en |= !use_ntuple ? 0 :
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
+ }
+
+ if (tcp_mask->hdr.src_port) {
+ filter->src_port_mask = tcp_mask->hdr.src_port;
+ en |= !use_ntuple ? 0 :
+ NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
+ }
+ break;
+ case RTE_FLOW_ITEM_TYPE_UDP:
+ udp_spec = item->spec;
+ udp_mask = item->mask;
+
+ if (udp_mask->hdr.dgram_len ||
+ udp_mask->hdr.dgram_cksum) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid UDP mask");
+ return -rte_errno;
+ }
+
+ filter->src_port = udp_spec->hdr.src_port;
+ filter->dst_port = udp_spec->hdr.dst_port;
+
+ if (use_ntuple)
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT |
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
+ else
+ en |= EM_FLOW_ALLOC_INPUT_EN_SRC_PORT |
+ EM_FLOW_ALLOC_INPUT_EN_DST_PORT;
+
+ if (udp_mask->hdr.dst_port) {
+ filter->dst_port_mask = udp_mask->hdr.dst_port;
+ en |= !use_ntuple ? 0 :
+ NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
+ }
+
+ if (udp_mask->hdr.src_port) {
+ filter->src_port_mask = udp_mask->hdr.src_port;
+ en |= !use_ntuple ? 0 :
+ NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
+ }
+ break;
+ case RTE_FLOW_ITEM_TYPE_VXLAN:
+ vxlan_spec = item->spec;
+ vxlan_mask = item->mask;
+ /* Check if VXLAN item is used to describe protocol.
+ * If yes, both spec and mask should be NULL.
+ * If no, both spec and mask shouldn't be NULL.
+ */
+ if ((!vxlan_spec && vxlan_mask) ||
+ (vxlan_spec && !vxlan_mask)) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid VXLAN item");
+ return -rte_errno;
+ }
+
+ if (vxlan_spec->rsvd1 || vxlan_spec->rsvd0[0] ||
+ vxlan_spec->rsvd0[1] || vxlan_spec->rsvd0[2] ||
+ vxlan_spec->flags != 0x8) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid VXLAN item");
+ return -rte_errno;
+ }
+
+ /* Check if VNI is masked. */
+ if (vxlan_spec && vxlan_mask) {
+ vni_masked =
+ !!memcmp(vxlan_mask->vni, vni_mask,
+ RTE_DIM(vni_mask));
+ if (vni_masked) {
+ rte_flow_error_set
+ (error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid VNI mask");
+ return -rte_errno;
+ }
+
+ rte_memcpy(((uint8_t *)&tenant_id_be + 1),
+ vxlan_spec->vni, 3);
+ filter->vni =
+ rte_be_to_cpu_32(tenant_id_be);
+ filter->tunnel_type =
+ CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN;
+ }
+ break;
+ case RTE_FLOW_ITEM_TYPE_NVGRE:
+ nvgre_spec = item->spec;
+ nvgre_mask = item->mask;
+ /* Check if NVGRE item is used to describe protocol.
+ * If yes, both spec and mask should be NULL.
+ * If no, both spec and mask shouldn't be NULL.
+ */
+ if ((!nvgre_spec && nvgre_mask) ||
+ (nvgre_spec && !nvgre_mask)) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid NVGRE item");
+ return -rte_errno;
+ }
+
+ if (nvgre_spec->c_k_s_rsvd0_ver != 0x2000 ||
+ nvgre_spec->protocol != 0x6558) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid NVGRE item");
+ return -rte_errno;
+ }
+
+ if (nvgre_spec && nvgre_mask) {
+ tni_masked =
+ !!memcmp(nvgre_mask->tni, tni_mask,
+ RTE_DIM(tni_mask));
+ if (tni_masked) {
+ rte_flow_error_set
+ (error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid TNI mask");
+ return -rte_errno;
+ }
+ rte_memcpy(((uint8_t *)&tenant_id_be + 1),
+ nvgre_spec->tni, 3);
+ filter->vni =
+ rte_be_to_cpu_32(tenant_id_be);
+ filter->tunnel_type =
+ CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE;
+ }
+ break;
+ case RTE_FLOW_ITEM_TYPE_VF:
+ vf_spec = item->spec;
+ vf = vf_spec->id;
+
+ if (!BNXT_PF(bp)) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Configuring on a VF!");
+ return -rte_errno;
+ }
+
+ if (vf >= bp->pdev->max_vfs) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Incorrect VF id!");
+ return -rte_errno;
+ }
+
+ if (!attr->transfer) {
+ rte_flow_error_set(error,
+ ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Matching VF traffic without"
+ " affecting it (transfer attribute)"
+ " is unsupported");
+ return -rte_errno;
+ }
+
+ filter->mirror_vnic_id =
+ dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
+ if (dflt_vnic < 0) {
+ /* This simply indicates there's no driver
+ * loaded. This is not an error.
+ */
+ rte_flow_error_set
+ (error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Unable to get default VNIC for VF");
+ return -rte_errno;
+ }
+
+ filter->mirror_vnic_id = dflt_vnic;
+ en |= NTUPLE_FLTR_ALLOC_INPUT_EN_MIRROR_VNIC_ID;
+ break;
+ default:
+ break;
+ }
+ item++;
+ }
+ filter->enables = en;
+
+ return 0;
+}
+
+/* Parse attributes */
+static int
+bnxt_flow_parse_attr(const struct rte_flow_attr *attr,
+ struct rte_flow_error *error)
+{
+ /* Must be input direction */
+ if (!attr->ingress) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
+ attr,
+ "Only support ingress.");
+ return -rte_errno;
+ }
+
+ /* Not supported */
+ if (attr->egress) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
+ attr,
+ "No support for egress.");
+ return -rte_errno;
+ }
+
+ /* Not supported */
+ if (attr->priority) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
+ attr,
+ "No support for priority.");
+ return -rte_errno;
+ }
+
+ /* Not supported */
+ if (attr->group) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
+ attr,
+ "No support for group.");
+ return -rte_errno;
+ }
+
+ return 0;
+}
+
+struct bnxt_filter_info *
+bnxt_get_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf,
+ struct bnxt_vnic_info *vnic)
+{
+ struct bnxt_filter_info *filter1, *f0;
+ struct bnxt_vnic_info *vnic0;
+ int rc;
+
+ vnic0 = STAILQ_FIRST(&bp->ff_pool[0]);
+ f0 = STAILQ_FIRST(&vnic0->filter);
+
+ /* This flow has same DST MAC as the port/l2 filter. */
+ if (memcmp(f0->l2_addr, nf->dst_macaddr, ETHER_ADDR_LEN) == 0)
+ return f0;
+
+ /* This flow needs DST MAC which is not same as port/l2 */
+ PMD_DRV_LOG(DEBUG, "Create L2 filter for DST MAC\n");
+ filter1 = bnxt_get_unused_filter(bp);
+ if (filter1 == NULL)
+ return NULL;
+
+ filter1->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
+ filter1->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
+ L2_FILTER_ALLOC_INPUT_EN_L2_ADDR_MASK;
+ memcpy(filter1->l2_addr, nf->dst_macaddr, ETHER_ADDR_LEN);
+ memset(filter1->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+ rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id,
+ filter1);
+ if (rc) {
+ bnxt_free_filter(bp, filter1);
+ return NULL;
+ }
+ return filter1;
+}
+
+static int
+bnxt_validate_and_parse_flow(struct rte_eth_dev *dev,
+ const struct rte_flow_item pattern[],
+ const struct rte_flow_action actions[],
+ const struct rte_flow_attr *attr,
+ struct rte_flow_error *error,
+ struct bnxt_filter_info *filter)
+{
+ const struct rte_flow_action *act =
+ bnxt_flow_non_void_action(actions);
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ const struct rte_flow_action_queue *act_q;
+ const struct rte_flow_action_vf *act_vf;
+ struct bnxt_vnic_info *vnic, *vnic0;
+ struct bnxt_filter_info *filter1;
+ uint32_t vf = 0;
+ int dflt_vnic;
+ int rc;
+
+ if (bp->eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS) {
+ PMD_DRV_LOG(ERR, "Cannot create flow on RSS queues\n");
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL,
+ "Cannot create flow on RSS queues");
+ rc = -rte_errno;
+ goto ret;
+ }
+
+ rc =
+ bnxt_validate_and_parse_flow_type(bp, attr, pattern, error, filter);
+ if (rc != 0)
+ goto ret;
+
+ rc = bnxt_flow_parse_attr(attr, error);
+ if (rc != 0)
+ goto ret;
+
+ /* Since we support ingress attribute only - right now. */
+ if (filter->filter_type == HWRM_CFA_EM_FILTER)
+ filter->flags = HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_PATH_RX;
+
+ switch (act->type) {
+ case RTE_FLOW_ACTION_TYPE_QUEUE:
+ /* Allow this flow. Redirect to a VNIC. */
+ act_q = (const struct rte_flow_action_queue *)act->conf;
+ if (act_q->index >= bp->rx_nr_rings) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "Invalid queue ID.");
+ rc = -rte_errno;
+ goto ret;
+ }
+ PMD_DRV_LOG(DEBUG, "Queue index %d\n", act_q->index);
+
+ vnic0 = STAILQ_FIRST(&bp->ff_pool[0]);
+ vnic = STAILQ_FIRST(&bp->ff_pool[act_q->index]);
+ if (vnic == NULL) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "No matching VNIC for queue ID.");
+ rc = -rte_errno;
+ goto ret;
+ }
+
+ filter->dst_id = vnic->fw_vnic_id;
+ filter1 = bnxt_get_l2_filter(bp, filter, vnic);
+ if (filter1 == NULL) {
+ rc = -ENOSPC;
+ goto ret;
+ }
+
+ filter->fw_l2_filter_id = filter1->fw_l2_filter_id;
+ PMD_DRV_LOG(DEBUG, "VNIC found\n");
+ break;
+ case RTE_FLOW_ACTION_TYPE_DROP:
+ vnic0 = STAILQ_FIRST(&bp->ff_pool[0]);
+ filter1 = bnxt_get_l2_filter(bp, filter, vnic0);
+ if (filter1 == NULL) {
+ rc = -ENOSPC;
+ goto ret;
+ }
+
+ filter->fw_l2_filter_id = filter1->fw_l2_filter_id;
+ if (filter->filter_type == HWRM_CFA_EM_FILTER)
+ filter->flags =
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_DROP;
+ else
+ filter->flags =
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP;
+ break;
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ vnic0 = STAILQ_FIRST(&bp->ff_pool[0]);
+ filter1 = bnxt_get_l2_filter(bp, filter, vnic0);
+ if (filter1 == NULL) {
+ rc = -ENOSPC;
+ goto ret;
+ }
+
+ filter->fw_l2_filter_id = filter1->fw_l2_filter_id;
+ filter->flags = HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_METER;
+ break;
+ case RTE_FLOW_ACTION_TYPE_VF:
+ act_vf = (const struct rte_flow_action_vf *)act->conf;
+ vf = act_vf->id;
+
+ if (!BNXT_PF(bp)) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "Configuring on a VF!");
+ rc = -rte_errno;
+ goto ret;
+ }
+
+ if (vf >= bp->pdev->max_vfs) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "Incorrect VF id!");
+ rc = -rte_errno;
+ goto ret;
+ }
+
+ filter->mirror_vnic_id =
+ dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
+ if (dflt_vnic < 0) {
+ /* This simply indicates there's no driver loaded.
+ * This is not an error.
+ */
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "Unable to get default VNIC for VF");
+ rc = -rte_errno;
+ goto ret;
+ }
+
+ filter->mirror_vnic_id = dflt_vnic;
+ filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_MIRROR_VNIC_ID;
+
+ vnic0 = STAILQ_FIRST(&bp->ff_pool[0]);
+ filter1 = bnxt_get_l2_filter(bp, filter, vnic0);
+ if (filter1 == NULL) {
+ rc = -ENOSPC;
+ goto ret;
+ }
+
+ filter->fw_l2_filter_id = filter1->fw_l2_filter_id;
+ break;
+
+ default:
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "Invalid action.");
+ rc = -rte_errno;
+ goto ret;
+ }
+
+ if (filter1) {
+ bnxt_free_filter(bp, filter1);
+ filter1->fw_l2_filter_id = -1;
+ }
+
+ act = bnxt_flow_non_void_action(++act);
+ if (act->type != RTE_FLOW_ACTION_TYPE_END) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "Invalid action.");
+ rc = -rte_errno;
+ goto ret;
+ }
+ret:
+ return rc;
+}
+
+static int
+bnxt_flow_validate(struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item pattern[],
+ const struct rte_flow_action actions[],
+ struct rte_flow_error *error)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_filter_info *filter;
+ int ret = 0;
+
+ ret = bnxt_flow_args_validate(attr, pattern, actions, error);
+ if (ret != 0)
+ return ret;
+
+ filter = bnxt_get_unused_filter(bp);
+ if (filter == NULL) {
+ PMD_DRV_LOG(ERR, "Not enough resources for a new flow.\n");
+ return -ENOMEM;
+ }
+
+ ret = bnxt_validate_and_parse_flow(dev, pattern, actions, attr,
+ error, filter);
+ /* No need to hold on to this filter if we are just validating flow */
+ filter->fw_l2_filter_id = UINT64_MAX;
+ bnxt_free_filter(bp, filter);
+
+ return ret;
+}
+
+static int
+bnxt_match_filter(struct bnxt *bp, struct bnxt_filter_info *nf)
+{
+ struct bnxt_filter_info *mf;
+ struct rte_flow *flow;
+ int i;
+
+ for (i = bp->nr_vnics - 1; i >= 0; i--) {
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+ STAILQ_FOREACH(flow, &vnic->flow_list, next) {
+ mf = flow->filter;
+
+ if (mf->filter_type == nf->filter_type &&
+ mf->flags == nf->flags &&
+ mf->src_port == nf->src_port &&
+ mf->src_port_mask == nf->src_port_mask &&
+ mf->dst_port == nf->dst_port &&
+ mf->dst_port_mask == nf->dst_port_mask &&
+ mf->ip_protocol == nf->ip_protocol &&
+ mf->ip_addr_type == nf->ip_addr_type &&
+ mf->ethertype == nf->ethertype &&
+ mf->vni == nf->vni &&
+ mf->tunnel_type == nf->tunnel_type &&
+ mf->l2_ovlan == nf->l2_ovlan &&
+ mf->l2_ovlan_mask == nf->l2_ovlan_mask &&
+ mf->l2_ivlan == nf->l2_ivlan &&
+ mf->l2_ivlan_mask == nf->l2_ivlan_mask &&
+ !memcmp(mf->l2_addr, nf->l2_addr, ETHER_ADDR_LEN) &&
+ !memcmp(mf->l2_addr_mask, nf->l2_addr_mask,
+ ETHER_ADDR_LEN) &&
+ !memcmp(mf->src_macaddr, nf->src_macaddr,
+ ETHER_ADDR_LEN) &&
+ !memcmp(mf->dst_macaddr, nf->dst_macaddr,
+ ETHER_ADDR_LEN) &&
+ !memcmp(mf->src_ipaddr, nf->src_ipaddr,
+ sizeof(nf->src_ipaddr)) &&
+ !memcmp(mf->src_ipaddr_mask, nf->src_ipaddr_mask,
+ sizeof(nf->src_ipaddr_mask)) &&
+ !memcmp(mf->dst_ipaddr, nf->dst_ipaddr,
+ sizeof(nf->dst_ipaddr)) &&
+ !memcmp(mf->dst_ipaddr_mask, nf->dst_ipaddr_mask,
+ sizeof(nf->dst_ipaddr_mask))) {
+ if (mf->dst_id == nf->dst_id)
+ return -EEXIST;
+ /*
+ * Same Flow, Different queue
+ * Clear the old ntuple filter
+ * Reuse the matching L2 filter
+ * ID for the new filter
+ */
+ nf->fw_l2_filter_id = mf->fw_l2_filter_id;
+ if (nf->filter_type == HWRM_CFA_EM_FILTER)
+ bnxt_hwrm_clear_em_filter(bp, mf);
+ if (nf->filter_type == HWRM_CFA_NTUPLE_FILTER)
+ bnxt_hwrm_clear_ntuple_filter(bp, mf);
+ /* Free the old filter, update flow
+ * with new filter
+ */
+ bnxt_free_filter(bp, mf);
+ flow->filter = nf;
+ return -EXDEV;
+ }
+ }
+ }
+ return 0;
+}
+
+static struct rte_flow *
+bnxt_flow_create(struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item pattern[],
+ const struct rte_flow_action actions[],
+ struct rte_flow_error *error)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_filter_info *filter;
+ struct bnxt_vnic_info *vnic = NULL;
+ bool update_flow = false;
+ struct rte_flow *flow;
+ unsigned int i;
+ int ret = 0;
+
+ flow = rte_zmalloc("bnxt_flow", sizeof(struct rte_flow), 0);
+ if (!flow) {
+ rte_flow_error_set(error, ENOMEM,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Failed to allocate memory");
+ return flow;
+ }
+
+ ret = bnxt_flow_args_validate(attr, pattern, actions, error);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Not a validate flow.\n");
+ goto free_flow;
+ }
+
+ filter = bnxt_get_unused_filter(bp);
+ if (filter == NULL) {
+ PMD_DRV_LOG(ERR, "Not enough resources for a new flow.\n");
+ goto free_flow;
+ }
+
+ ret = bnxt_validate_and_parse_flow(dev, pattern, actions, attr,
+ error, filter);
+ if (ret != 0)
+ goto free_filter;
+
+ ret = bnxt_match_filter(bp, filter);
+ if (ret == -EEXIST) {
+ PMD_DRV_LOG(DEBUG, "Flow already exists.\n");
+ /* Clear the filter that was created as part of
+ * validate_and_parse_flow() above
+ */
+ bnxt_hwrm_clear_l2_filter(bp, filter);
+ goto free_filter;
+ } else if (ret == -EXDEV) {
+ PMD_DRV_LOG(DEBUG, "Flow with same pattern exists\n");
+ PMD_DRV_LOG(DEBUG, "Updating with different destination\n");
+ update_flow = true;
+ }
+
+ if (filter->filter_type == HWRM_CFA_EM_FILTER) {
+ filter->enables |=
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_L2_FILTER_ID;
+ ret = bnxt_hwrm_set_em_filter(bp, filter->dst_id, filter);
+ }
+
+ if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) {
+ filter->enables |=
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID;
+ ret = bnxt_hwrm_set_ntuple_filter(bp, filter->dst_id, filter);
+ }
+
+ for (i = 0; i < bp->nr_vnics; i++) {
+ vnic = &bp->vnic_info[i];
+ if (filter->dst_id == vnic->fw_vnic_id)
+ break;
+ }
+
+ if (!ret) {
+ flow->filter = filter;
+ flow->vnic = vnic;
+ if (update_flow) {
+ ret = -EXDEV;
+ goto free_flow;
+ }
+ PMD_DRV_LOG(ERR, "Successfully created flow.\n");
+ STAILQ_INSERT_TAIL(&vnic->flow_list, flow, next);
+ return flow;
+ }
+free_filter:
+ bnxt_free_filter(bp, filter);
+free_flow:
+ if (ret == -EEXIST)
+ rte_flow_error_set(error, ret,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Matching Flow exists.");
+ else if (ret == -EXDEV)
+ rte_flow_error_set(error, ret,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Flow with pattern exists, updating destination queue");
+ else
+ rte_flow_error_set(error, -ret,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Failed to create flow.");
+ rte_free(flow);
+ flow = NULL;
+ return flow;
+}
+
+static int
+bnxt_flow_destroy(struct rte_eth_dev *dev,
+ struct rte_flow *flow,
+ struct rte_flow_error *error)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_filter_info *filter = flow->filter;
+ struct bnxt_vnic_info *vnic = flow->vnic;
+ int ret = 0;
+
+ ret = bnxt_match_filter(bp, filter);
+ if (ret == 0)
+ PMD_DRV_LOG(ERR, "Could not find matching flow\n");
+ if (filter->filter_type == HWRM_CFA_EM_FILTER)
+ ret = bnxt_hwrm_clear_em_filter(bp, filter);
+ if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
+ ret = bnxt_hwrm_clear_ntuple_filter(bp, filter);
+ else
+ ret = bnxt_hwrm_clear_l2_filter(bp, filter);
+ if (!ret) {
+ STAILQ_REMOVE(&vnic->flow_list, flow, rte_flow, next);
+ rte_free(flow);
+ } else {
+ rte_flow_error_set(error, -ret,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Failed to destroy flow.");
+ }
+
+ return ret;
+}
+
+static int
+bnxt_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_vnic_info *vnic;
+ struct rte_flow *flow;
+ unsigned int i;
+ int ret = 0;
+
+ for (i = 0; i < bp->nr_vnics; i++) {
+ vnic = &bp->vnic_info[i];
+ STAILQ_FOREACH(flow, &vnic->flow_list, next) {
+ struct bnxt_filter_info *filter = flow->filter;
+
+ if (filter->filter_type == HWRM_CFA_EM_FILTER)
+ ret = bnxt_hwrm_clear_em_filter(bp, filter);
+ if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
+ ret = bnxt_hwrm_clear_ntuple_filter(bp, filter);
+
+ if (ret) {
+ rte_flow_error_set
+ (error,
+ -ret,
+ RTE_FLOW_ERROR_TYPE_HANDLE,
+ NULL,
+ "Failed to flush flow in HW.");
+ return -rte_errno;
+ }
+
+ STAILQ_REMOVE(&vnic->flow_list, flow,
+ rte_flow, next);
+ rte_free(flow);
+ }
+ }
+
+ return ret;
+}
+
+const struct rte_flow_ops bnxt_flow_ops = {
+ .validate = bnxt_flow_validate,
+ .create = bnxt_flow_create,
+ .destroy = bnxt_flow_destroy,
+ .flush = bnxt_flow_flush,
+};
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_hwrm.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_hwrm.c
new file mode 100644
index 00000000..c682488a
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_hwrm.c
@@ -0,0 +1,3947 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <unistd.h>
+
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_version.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
+#include "bnxt_ring.h"
+#include "bnxt_txq.h"
+#include "bnxt_txr.h"
+#include "bnxt_vnic.h"
+#include "hsi_struct_def_dpdk.h"
+
+#include <rte_io.h>
+
+#define HWRM_CMD_TIMEOUT 10000
+#define HWRM_SPEC_CODE_1_8_3 0x10803
+#define HWRM_VERSION_1_9_1 0x10901
+
+struct bnxt_plcmodes_cfg {
+ uint32_t flags;
+ uint16_t jumbo_thresh;
+ uint16_t hds_offset;
+ uint16_t hds_threshold;
+};
+
+static int page_getenum(size_t size)
+{
+ if (size <= 1 << 4)
+ return 4;
+ if (size <= 1 << 12)
+ return 12;
+ if (size <= 1 << 13)
+ return 13;
+ if (size <= 1 << 16)
+ return 16;
+ if (size <= 1 << 21)
+ return 21;
+ if (size <= 1 << 22)
+ return 22;
+ if (size <= 1 << 30)
+ return 30;
+ PMD_DRV_LOG(ERR, "Page size %zu out of range\n", size);
+ return sizeof(void *) * 8 - 1;
+}
+
+static int page_roundup(size_t size)
+{
+ return 1 << page_getenum(size);
+}
+
+/*
+ * 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(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;
+ uint16_t max_req_len = bp->max_req_len;
+ struct hwrm_short_input short_input = { 0 };
+
+ if (bp->flags & BNXT_FLAG_SHORT_CMD) {
+ void *short_cmd_req = bp->hwrm_short_cmd_req_addr;
+
+ memset(short_cmd_req, 0, bp->max_req_len);
+ memcpy(short_cmd_req, req, msg_len);
+
+ short_input.req_type = rte_cpu_to_le_16(req->req_type);
+ short_input.signature = rte_cpu_to_le_16(
+ HWRM_SHORT_INPUT_SIGNATURE_SHORT_CMD);
+ short_input.size = rte_cpu_to_le_16(msg_len);
+ short_input.req_addr =
+ rte_cpu_to_le_64(bp->hwrm_short_cmd_req_dma_addr);
+
+ data = (uint32_t *)&short_input;
+ msg_len = sizeof(short_input);
+
+ /* Sync memory write before updating doorbell */
+ rte_wmb();
+
+ max_req_len = BNXT_HWRM_SHORT_REQ_LEN;
+ }
+
+ /* Write request msg to hwrm channel */
+ for (i = 0; i < msg_len; i += 4) {
+ bar = (uint8_t *)bp->bar0 + i;
+ rte_write32(*data, bar);
+ data++;
+ }
+
+ /* Zero the rest of the request space */
+ for (; i < max_req_len; i += 4) {
+ bar = (uint8_t *)bp->bar0 + i;
+ rte_write32(0, bar);
+ }
+
+ /* Ring channel doorbell */
+ bar = (uint8_t *)bp->bar0 + 0x100;
+ rte_write32(1, bar);
+
+ /* 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) {
+ PMD_DRV_LOG(ERR, "Error sending msg 0x%04x\n",
+ req->req_type);
+ goto err_ret;
+ }
+ return 0;
+
+err_ret:
+ return -1;
+}
+
+/*
+ * HWRM_PREP() should be used to prepare *ALL* HWRM commands. It grabs the
+ * spinlock, and does initial processing.
+ *
+ * HWRM_CHECK_RESULT() returns errors on failure and may not be used. It
+ * releases the spinlock only if it returns. If the regular int return codes
+ * are not used by the function, HWRM_CHECK_RESULT() should not be used
+ * directly, rather it should be copied and modified to suit the function.
+ *
+ * HWRM_UNLOCK() must be called after all response processing is completed.
+ */
+#define HWRM_PREP(req, type) do { \
+ rte_spinlock_lock(&bp->hwrm_lock); \
+ 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(-1); \
+ 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); \
+} while (0)
+
+#define HWRM_CHECK_RESULT_SILENT() do {\
+ if (rc) { \
+ rte_spinlock_unlock(&bp->hwrm_lock); \
+ return rc; \
+ } \
+ if (resp->error_code) { \
+ rc = rte_le_to_cpu_16(resp->error_code); \
+ rte_spinlock_unlock(&bp->hwrm_lock); \
+ return rc; \
+ } \
+} while (0)
+
+#define HWRM_CHECK_RESULT() do {\
+ if (rc) { \
+ PMD_DRV_LOG(ERR, "failed rc:%d\n", rc); \
+ rte_spinlock_unlock(&bp->hwrm_lock); \
+ if (rc == HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED) \
+ rc = -EACCES; \
+ else if (rc > 0) \
+ rc = -EINVAL; \
+ return rc; \
+ } \
+ if (resp->error_code) { \
+ rc = rte_le_to_cpu_16(resp->error_code); \
+ if (resp->resp_len >= 16) { \
+ struct hwrm_err_output *tmp_hwrm_err_op = \
+ (void *)resp; \
+ PMD_DRV_LOG(ERR, \
+ "error %d:%d:%08x:%04x\n", \
+ rc, tmp_hwrm_err_op->cmd_err, \
+ rte_le_to_cpu_32(\
+ tmp_hwrm_err_op->opaque_0), \
+ rte_le_to_cpu_16(\
+ tmp_hwrm_err_op->opaque_1)); \
+ } else { \
+ PMD_DRV_LOG(ERR, "error %d\n", rc); \
+ } \
+ rte_spinlock_unlock(&bp->hwrm_lock); \
+ if (rc == HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED) \
+ rc = -EACCES; \
+ else if (rc > 0) \
+ rc = -EINVAL; \
+ return rc; \
+ } \
+} while (0)
+
+#define HWRM_UNLOCK() rte_spinlock_unlock(&bp->hwrm_lock)
+
+int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_cfa_l2_set_rx_mask_input req = {.req_type = 0 };
+ struct hwrm_cfa_l2_set_rx_mask_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, CFA_L2_SET_RX_MASK);
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+ req.mask = 0;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic,
+ uint16_t vlan_count,
+ struct bnxt_vlan_table_entry *vlan_table)
+{
+ int rc = 0;
+ struct hwrm_cfa_l2_set_rx_mask_input req = {.req_type = 0 };
+ struct hwrm_cfa_l2_set_rx_mask_output *resp = bp->hwrm_cmd_resp_addr;
+ uint32_t mask = 0;
+
+ if (vnic->fw_vnic_id == INVALID_HW_RING_ID)
+ return rc;
+
+ HWRM_PREP(req, CFA_L2_SET_RX_MASK);
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+
+ /* FIXME add multicast flag, when multicast adding options is supported
+ * by ethtool.
+ */
+ if (vnic->flags & BNXT_VNIC_INFO_BCAST)
+ mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST;
+ if (vnic->flags & BNXT_VNIC_INFO_UNTAGGED)
+ mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN;
+ if (vnic->flags & BNXT_VNIC_INFO_PROMISC)
+ mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS;
+ if (vnic->flags & BNXT_VNIC_INFO_ALLMULTI)
+ mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST;
+ if (vnic->flags & BNXT_VNIC_INFO_MCAST)
+ mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
+ if (vnic->mc_addr_cnt) {
+ mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
+ req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt);
+ req.mc_tbl_addr = rte_cpu_to_le_64(vnic->mc_list_dma_addr);
+ }
+ if (vlan_table) {
+ if (!(mask & HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN))
+ mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
+ req.vlan_tag_tbl_addr = rte_cpu_to_le_64(
+ rte_mem_virt2iova(vlan_table));
+ req.num_vlan_tags = rte_cpu_to_le_32((uint32_t)vlan_count);
+ }
+ req.mask = rte_cpu_to_le_32(mask);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_cfa_vlan_antispoof_cfg(struct bnxt *bp, uint16_t fid,
+ uint16_t vlan_count,
+ struct bnxt_vlan_antispoof_table_entry *vlan_table)
+{
+ int rc = 0;
+ struct hwrm_cfa_vlan_antispoof_cfg_input req = {.req_type = 0 };
+ struct hwrm_cfa_vlan_antispoof_cfg_output *resp =
+ bp->hwrm_cmd_resp_addr;
+
+ /*
+ * Older HWRM versions did not support this command, and the set_rx_mask
+ * list was used for anti-spoof. In 1.8.0, the TX path configuration was
+ * removed from set_rx_mask call, and this command was added.
+ *
+ * This command is also present from 1.7.8.11 and higher,
+ * as well as 1.7.8.0
+ */
+ if (bp->fw_ver < ((1 << 24) | (8 << 16))) {
+ if (bp->fw_ver != ((1 << 24) | (7 << 16) | (8 << 8))) {
+ if (bp->fw_ver < ((1 << 24) | (7 << 16) | (8 << 8) |
+ (11)))
+ return 0;
+ }
+ }
+ HWRM_PREP(req, CFA_VLAN_ANTISPOOF_CFG);
+ req.fid = rte_cpu_to_le_16(fid);
+
+ req.vlan_tag_mask_tbl_addr =
+ rte_cpu_to_le_64(rte_mem_virt2iova(vlan_table));
+ req.num_vlan_entries = rte_cpu_to_le_32((uint32_t)vlan_count);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_clear_l2_filter(struct bnxt *bp,
+ struct bnxt_filter_info *filter)
+{
+ int rc = 0;
+ struct hwrm_cfa_l2_filter_free_input req = {.req_type = 0 };
+ struct hwrm_cfa_l2_filter_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (filter->fw_l2_filter_id == UINT64_MAX)
+ return 0;
+
+ HWRM_PREP(req, CFA_L2_FILTER_FREE);
+
+ req.l2_filter_id = rte_cpu_to_le_64(filter->fw_l2_filter_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ filter->fw_l2_filter_id = UINT64_MAX;
+
+ return 0;
+}
+
+int bnxt_hwrm_set_l2_filter(struct bnxt *bp,
+ uint16_t dst_id,
+ struct bnxt_filter_info *filter)
+{
+ int rc = 0;
+ struct hwrm_cfa_l2_filter_alloc_input req = {.req_type = 0 };
+ struct hwrm_cfa_l2_filter_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ const struct rte_eth_vmdq_rx_conf *conf =
+ &dev_conf->rx_adv_conf.vmdq_rx_conf;
+ uint32_t enables = 0;
+ uint16_t j = dst_id - 1;
+
+ //TODO: Is there a better way to add VLANs to each VNIC in case of VMDQ
+ if ((dev_conf->rxmode.mq_mode & ETH_MQ_RX_VMDQ_FLAG) &&
+ conf->pool_map[j].pools & (1UL << j)) {
+ PMD_DRV_LOG(DEBUG,
+ "Add vlan %u to vmdq pool %u\n",
+ conf->pool_map[j].vlan_id, j);
+
+ filter->l2_ivlan = conf->pool_map[j].vlan_id;
+ filter->enables |=
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN |
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK;
+ }
+
+ if (filter->fw_l2_filter_id != UINT64_MAX)
+ bnxt_hwrm_clear_l2_filter(bp, filter);
+
+ HWRM_PREP(req, CFA_L2_FILTER_ALLOC);
+
+ req.flags = rte_cpu_to_le_32(filter->flags);
+
+ enables = filter->enables |
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID;
+ req.dst_id = rte_cpu_to_le_16(dst_id);
+
+ if (enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR)
+ memcpy(req.l2_addr, filter->l2_addr,
+ ETHER_ADDR_LEN);
+ if (enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK)
+ memcpy(req.l2_addr_mask, filter->l2_addr_mask,
+ ETHER_ADDR_LEN);
+ if (enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN)
+ req.l2_ovlan = filter->l2_ovlan;
+ if (enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN)
+ req.l2_ivlan = filter->l2_ivlan;
+ if (enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK)
+ req.l2_ovlan_mask = filter->l2_ovlan_mask;
+ if (enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK)
+ req.l2_ivlan_mask = filter->l2_ivlan_mask;
+ if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID)
+ req.src_id = rte_cpu_to_le_32(filter->src_id);
+ if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE)
+ req.src_type = filter->src_type;
+
+ req.enables = rte_cpu_to_le_32(enables);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ filter->fw_l2_filter_id = rte_le_to_cpu_64(resp->l2_filter_id);
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
+{
+ struct hwrm_port_mac_cfg_input req = {.req_type = 0};
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ uint32_t flags = 0;
+ int rc;
+
+ if (!ptp)
+ return 0;
+
+ HWRM_PREP(req, PORT_MAC_CFG);
+
+ if (ptp->rx_filter)
+ flags |= HWRM_PORT_MAC_CFG_INPUT_FLAGS_PTP_RX_TS_CAPTURE_ENABLE;
+ else
+ flags |=
+ HWRM_PORT_MAC_CFG_INPUT_FLAGS_PTP_RX_TS_CAPTURE_DISABLE;
+ if (ptp->tx_tstamp_en)
+ flags |= HWRM_PORT_MAC_CFG_INPUT_FLAGS_PTP_TX_TS_CAPTURE_ENABLE;
+ else
+ flags |=
+ HWRM_PORT_MAC_CFG_INPUT_FLAGS_PTP_TX_TS_CAPTURE_DISABLE;
+ req.flags = rte_cpu_to_le_32(flags);
+ req.enables = rte_cpu_to_le_32
+ (HWRM_PORT_MAC_CFG_INPUT_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE);
+ req.rx_ts_capture_ptp_msg_type = rte_cpu_to_le_16(ptp->rxctl);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+static int bnxt_hwrm_ptp_qcfg(struct bnxt *bp)
+{
+ int rc = 0;
+ struct hwrm_port_mac_ptp_qcfg_input req = {.req_type = 0};
+ struct hwrm_port_mac_ptp_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+
+/* if (bp->hwrm_spec_code < 0x10801 || ptp) TBD */
+ if (ptp)
+ return 0;
+
+ HWRM_PREP(req, PORT_MAC_PTP_QCFG);
+
+ req.port_id = rte_cpu_to_le_16(bp->pf.port_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ if (!(resp->flags & HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_DIRECT_ACCESS))
+ return 0;
+
+ ptp = rte_zmalloc("ptp_cfg", sizeof(*ptp), 0);
+ if (!ptp)
+ return -ENOMEM;
+
+ ptp->rx_regs[BNXT_PTP_RX_TS_L] =
+ rte_le_to_cpu_32(resp->rx_ts_reg_off_lower);
+ ptp->rx_regs[BNXT_PTP_RX_TS_H] =
+ rte_le_to_cpu_32(resp->rx_ts_reg_off_upper);
+ ptp->rx_regs[BNXT_PTP_RX_SEQ] =
+ rte_le_to_cpu_32(resp->rx_ts_reg_off_seq_id);
+ ptp->rx_regs[BNXT_PTP_RX_FIFO] =
+ rte_le_to_cpu_32(resp->rx_ts_reg_off_fifo);
+ ptp->rx_regs[BNXT_PTP_RX_FIFO_ADV] =
+ rte_le_to_cpu_32(resp->rx_ts_reg_off_fifo_adv);
+ ptp->tx_regs[BNXT_PTP_TX_TS_L] =
+ rte_le_to_cpu_32(resp->tx_ts_reg_off_lower);
+ ptp->tx_regs[BNXT_PTP_TX_TS_H] =
+ rte_le_to_cpu_32(resp->tx_ts_reg_off_upper);
+ ptp->tx_regs[BNXT_PTP_TX_SEQ] =
+ rte_le_to_cpu_32(resp->tx_ts_reg_off_seq_id);
+ ptp->tx_regs[BNXT_PTP_TX_FIFO] =
+ rte_le_to_cpu_32(resp->tx_ts_reg_off_fifo);
+
+ ptp->bp = bp;
+ bp->ptp_cfg = ptp;
+
+ return 0;
+}
+
+static 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;
+ uint16_t new_max_vfs;
+ uint32_t flags;
+ int i;
+
+ HWRM_PREP(req, FUNC_QCAPS);
+
+ req.fid = rte_cpu_to_le_16(0xffff);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ bp->max_ring_grps = rte_le_to_cpu_32(resp->max_hw_ring_grps);
+ flags = rte_le_to_cpu_32(resp->flags);
+ if (BNXT_PF(bp)) {
+ bp->pf.port_id = resp->port_id;
+ bp->pf.first_vf_id = rte_le_to_cpu_16(resp->first_vf_id);
+ bp->pf.total_vfs = rte_le_to_cpu_16(resp->max_vfs);
+ new_max_vfs = bp->pdev->max_vfs;
+ if (new_max_vfs != bp->pf.max_vfs) {
+ if (bp->pf.vf_info)
+ rte_free(bp->pf.vf_info);
+ bp->pf.vf_info = rte_malloc("bnxt_vf_info",
+ sizeof(bp->pf.vf_info[0]) * new_max_vfs, 0);
+ bp->pf.max_vfs = new_max_vfs;
+ for (i = 0; i < new_max_vfs; i++) {
+ bp->pf.vf_info[i].fid = bp->pf.first_vf_id + i;
+ bp->pf.vf_info[i].vlan_table =
+ rte_zmalloc("VF VLAN table",
+ getpagesize(),
+ getpagesize());
+ if (bp->pf.vf_info[i].vlan_table == NULL)
+ PMD_DRV_LOG(ERR,
+ "Fail to alloc VLAN table for VF %d\n",
+ i);
+ else
+ rte_mem_lock_page(
+ bp->pf.vf_info[i].vlan_table);
+ bp->pf.vf_info[i].vlan_as_table =
+ rte_zmalloc("VF VLAN AS table",
+ getpagesize(),
+ getpagesize());
+ if (bp->pf.vf_info[i].vlan_as_table == NULL)
+ PMD_DRV_LOG(ERR,
+ "Alloc VLAN AS table for VF %d fail\n",
+ i);
+ else
+ rte_mem_lock_page(
+ bp->pf.vf_info[i].vlan_as_table);
+ STAILQ_INIT(&bp->pf.vf_info[i].filter);
+ }
+ }
+ }
+
+ bp->fw_fid = rte_le_to_cpu_32(resp->fid);
+ memcpy(bp->dflt_mac_addr, &resp->mac_address, ETHER_ADDR_LEN);
+ bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx);
+ bp->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings);
+ bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings);
+ bp->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings);
+ bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
+ /* TODO: For now, do not support VMDq/RFS on VFs. */
+ if (BNXT_PF(bp)) {
+ if (bp->pf.max_vfs)
+ bp->max_vnics = 1;
+ else
+ bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics);
+ } else {
+ bp->max_vnics = 1;
+ }
+ bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx);
+ if (BNXT_PF(bp)) {
+ bp->pf.total_vnics = rte_le_to_cpu_16(resp->max_vnics);
+ if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED) {
+ bp->flags |= BNXT_FLAG_PTP_SUPPORTED;
+ PMD_DRV_LOG(INFO, "PTP SUPPORTED\n");
+ HWRM_UNLOCK();
+ bnxt_hwrm_ptp_qcfg(bp);
+ }
+ }
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_qcaps(struct bnxt *bp)
+{
+ int rc;
+
+ rc = __bnxt_hwrm_func_qcaps(bp);
+ if (!rc && bp->hwrm_spec_code >= HWRM_SPEC_CODE_1_8_3) {
+ rc = bnxt_hwrm_func_resc_qcaps(bp);
+ if (!rc)
+ bp->flags |= BNXT_FLAG_NEW_RM;
+ }
+
+ return rc;
+}
+
+int bnxt_hwrm_func_reset(struct bnxt *bp)
+{
+ int rc = 0;
+ struct hwrm_func_reset_input req = {.req_type = 0 };
+ struct hwrm_func_reset_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_RESET);
+
+ req.enables = rte_cpu_to_le_32(0);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_driver_register(struct bnxt *bp)
+{
+ int rc;
+ struct hwrm_func_drv_rgtr_input req = {.req_type = 0 };
+ struct hwrm_func_drv_rgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (bp->flags & BNXT_FLAG_REGISTERED)
+ return 0;
+
+ HWRM_PREP(req, FUNC_DRV_RGTR);
+ req.enables = rte_cpu_to_le_32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
+ HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD);
+ req.ver_maj = RTE_VER_YEAR;
+ req.ver_min = RTE_VER_MONTH;
+ req.ver_upd = RTE_VER_MINOR;
+
+ if (BNXT_PF(bp)) {
+ req.enables |= rte_cpu_to_le_32(
+ HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_REQ_FWD);
+ memcpy(req.vf_req_fwd, bp->pf.vf_req_fwd,
+ RTE_MIN(sizeof(req.vf_req_fwd),
+ sizeof(bp->pf.vf_req_fwd)));
+
+ /*
+ * PF can sniff HWRM API issued by VF. This can be set up by
+ * linux driver and inherited by the DPDK PF driver. Clear
+ * this HWRM sniffer list in FW because DPDK PF driver does
+ * not support this.
+ */
+ req.flags =
+ rte_cpu_to_le_32(HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_NONE_MODE);
+ }
+
+ req.async_event_fwd[0] |=
+ rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_LINK_STATUS_CHANGE |
+ ASYNC_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED |
+ ASYNC_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE);
+ req.async_event_fwd[1] |=
+ rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_PF_DRVR_UNLOAD |
+ ASYNC_CMPL_EVENT_ID_VF_CFG_CHANGE);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ bp->flags |= BNXT_FLAG_REGISTERED;
+
+ return rc;
+}
+
+int bnxt_hwrm_check_vf_rings(struct bnxt *bp)
+{
+ if (!(BNXT_VF(bp) && (bp->flags & BNXT_FLAG_NEW_RM)))
+ return 0;
+
+ return bnxt_hwrm_func_reserve_vf_resc(bp, true);
+}
+
+int bnxt_hwrm_func_reserve_vf_resc(struct bnxt *bp, bool test)
+{
+ int rc;
+ uint32_t flags = 0;
+ uint32_t enables;
+ struct hwrm_func_vf_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_func_vf_cfg_input req = {0};
+
+ HWRM_PREP(req, FUNC_VF_CFG);
+
+ req.enables = rte_cpu_to_le_32
+ (HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+ HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+ HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+ HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+ HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS |
+ HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_VNICS);
+
+ req.num_tx_rings = rte_cpu_to_le_16(bp->tx_nr_rings);
+ req.num_rx_rings = rte_cpu_to_le_16(bp->rx_nr_rings *
+ AGG_RING_MULTIPLIER);
+ req.num_stat_ctxs = rte_cpu_to_le_16(bp->rx_nr_rings + bp->tx_nr_rings);
+ req.num_cmpl_rings = rte_cpu_to_le_16(bp->rx_nr_rings +
+ bp->tx_nr_rings);
+ req.num_hw_ring_grps = rte_cpu_to_le_16(bp->rx_nr_rings);
+ req.num_vnics = rte_cpu_to_le_16(bp->rx_nr_rings);
+ if (bp->vf_resv_strategy ==
+ HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MINIMAL_STATIC) {
+ enables = HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_VNICS |
+ HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+ HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS;
+ req.enables |= rte_cpu_to_le_32(enables);
+ req.num_rsscos_ctxs = rte_cpu_to_le_16(BNXT_VF_RSV_NUM_RSS_CTX);
+ req.num_l2_ctxs = rte_cpu_to_le_16(BNXT_VF_RSV_NUM_L2_CTX);
+ req.num_vnics = rte_cpu_to_le_16(BNXT_VF_RSV_NUM_VNIC);
+ }
+
+ if (test)
+ flags = HWRM_FUNC_VF_CFG_INPUT_FLAGS_TX_ASSETS_TEST |
+ HWRM_FUNC_VF_CFG_INPUT_FLAGS_RX_ASSETS_TEST |
+ HWRM_FUNC_VF_CFG_INPUT_FLAGS_CMPL_ASSETS_TEST |
+ HWRM_FUNC_VF_CFG_INPUT_FLAGS_RING_GRP_ASSETS_TEST |
+ HWRM_FUNC_VF_CFG_INPUT_FLAGS_STAT_CTX_ASSETS_TEST |
+ HWRM_FUNC_VF_CFG_INPUT_FLAGS_VNIC_ASSETS_TEST;
+
+ req.flags = rte_cpu_to_le_32(flags);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ if (test)
+ HWRM_CHECK_RESULT_SILENT();
+ else
+ HWRM_CHECK_RESULT();
+
+ HWRM_UNLOCK();
+ return rc;
+}
+
+int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp)
+{
+ int rc;
+ struct hwrm_func_resource_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_func_resource_qcaps_input req = {0};
+
+ HWRM_PREP(req, FUNC_RESOURCE_QCAPS);
+ req.fid = rte_cpu_to_le_16(0xffff);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ if (BNXT_VF(bp)) {
+ bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx);
+ bp->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings);
+ bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings);
+ bp->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings);
+ bp->max_ring_grps = rte_le_to_cpu_32(resp->max_hw_ring_grps);
+ bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
+ bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics);
+ bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx);
+ }
+ bp->vf_resv_strategy = rte_le_to_cpu_16(resp->vf_reservation_strategy);
+ if (bp->vf_resv_strategy >
+ HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MINIMAL_STATIC)
+ bp->vf_resv_strategy =
+ HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MAXIMAL;
+
+ HWRM_UNLOCK();
+ 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];
+ uint32_t dev_caps_cfg;
+
+ bp->max_req_len = HWRM_MAX_REQ_LEN;
+ HWRM_PREP(req, VER_GET);
+
+ req.hwrm_intf_maj = HWRM_VERSION_MAJOR;
+ req.hwrm_intf_min = HWRM_VERSION_MINOR;
+ req.hwrm_intf_upd = HWRM_VERSION_UPDATE;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ PMD_DRV_LOG(INFO, "%d.%d.%d:%d.%d.%d\n",
+ resp->hwrm_intf_maj_8b, resp->hwrm_intf_min_8b,
+ resp->hwrm_intf_upd_8b, resp->hwrm_fw_maj_8b,
+ resp->hwrm_fw_min_8b, resp->hwrm_fw_bld_8b);
+ bp->fw_ver = (resp->hwrm_fw_maj_8b << 24) |
+ (resp->hwrm_fw_min_8b << 16) |
+ (resp->hwrm_fw_bld_8b << 8) |
+ resp->hwrm_fw_rsvd_8b;
+ PMD_DRV_LOG(INFO, "Driver HWRM version: %d.%d.%d\n",
+ HWRM_VERSION_MAJOR, HWRM_VERSION_MINOR, HWRM_VERSION_UPDATE);
+
+ my_version = HWRM_VERSION_MAJOR << 16;
+ my_version |= HWRM_VERSION_MINOR << 8;
+ my_version |= HWRM_VERSION_UPDATE;
+
+ fw_version = resp->hwrm_intf_maj_8b << 16;
+ fw_version |= resp->hwrm_intf_min_8b << 8;
+ fw_version |= resp->hwrm_intf_upd_8b;
+ bp->hwrm_spec_code = fw_version;
+
+ if (resp->hwrm_intf_maj_8b != HWRM_VERSION_MAJOR) {
+ PMD_DRV_LOG(ERR, "Unsupported firmware API version\n");
+ rc = -EINVAL;
+ goto error;
+ }
+
+ if (my_version != fw_version) {
+ PMD_DRV_LOG(INFO, "BNXT Driver/HWRM API mismatch.\n");
+ if (my_version < fw_version) {
+ PMD_DRV_LOG(INFO,
+ "Firmware API version is newer than driver.\n");
+ PMD_DRV_LOG(INFO,
+ "The driver may be missing features.\n");
+ } else {
+ PMD_DRV_LOG(INFO,
+ "Firmware API version is older than driver.\n");
+ PMD_DRV_LOG(INFO,
+ "Not all driver features may be functional.\n");
+ }
+ }
+
+ if (bp->max_req_len > resp->max_req_win_len) {
+ PMD_DRV_LOG(ERR, "Unsupported request length\n");
+ rc = -EINVAL;
+ }
+ bp->max_req_len = rte_le_to_cpu_16(resp->max_req_win_len);
+ max_resp_len = resp->max_resp_len;
+ dev_caps_cfg = rte_le_to_cpu_32(resp->dev_caps_cfg);
+
+ 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;
+ }
+ rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
+ bp->hwrm_cmd_resp_dma_addr =
+ rte_mem_virt2iova(bp->hwrm_cmd_resp_addr);
+ if (bp->hwrm_cmd_resp_dma_addr == 0) {
+ PMD_DRV_LOG(ERR,
+ "Unable to map response buffer to physical memory.\n");
+ rc = -ENOMEM;
+ goto error;
+ }
+ bp->max_resp_len = max_resp_len;
+ }
+
+ if ((dev_caps_cfg &
+ HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) &&
+ (dev_caps_cfg &
+ HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_REQUIRED)) {
+ PMD_DRV_LOG(DEBUG, "Short command supported\n");
+
+ rte_free(bp->hwrm_short_cmd_req_addr);
+
+ bp->hwrm_short_cmd_req_addr = rte_malloc(type,
+ bp->max_req_len, 0);
+ if (bp->hwrm_short_cmd_req_addr == NULL) {
+ rc = -ENOMEM;
+ goto error;
+ }
+ rte_mem_lock_page(bp->hwrm_short_cmd_req_addr);
+ bp->hwrm_short_cmd_req_dma_addr =
+ rte_mem_virt2iova(bp->hwrm_short_cmd_req_addr);
+ if (bp->hwrm_short_cmd_req_dma_addr == 0) {
+ rte_free(bp->hwrm_short_cmd_req_addr);
+ PMD_DRV_LOG(ERR,
+ "Unable to map buffer to physical memory.\n");
+ rc = -ENOMEM;
+ goto error;
+ }
+
+ bp->flags |= BNXT_FLAG_SHORT_CMD;
+ }
+
+error:
+ HWRM_UNLOCK();
+ return rc;
+}
+
+int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags)
+{
+ int rc;
+ struct hwrm_func_drv_unrgtr_input req = {.req_type = 0 };
+ struct hwrm_func_drv_unrgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (!(bp->flags & BNXT_FLAG_REGISTERED))
+ return 0;
+
+ HWRM_PREP(req, FUNC_DRV_UNRGTR);
+ req.flags = flags;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ bp->flags &= ~BNXT_FLAG_REGISTERED;
+
+ return rc;
+}
+
+static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
+{
+ int rc = 0;
+ struct hwrm_port_phy_cfg_input req = {0};
+ struct hwrm_port_phy_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ uint32_t enables = 0;
+
+ HWRM_PREP(req, PORT_PHY_CFG);
+
+ if (conf->link_up) {
+ /* Setting Fixed Speed. But AutoNeg is ON, So disable it */
+ if (bp->link_info.auto_mode && conf->link_speed) {
+ req.auto_mode = HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE;
+ PMD_DRV_LOG(DEBUG, "Disabling AutoNeg\n");
+ }
+
+ req.flags = rte_cpu_to_le_32(conf->phy_flags);
+ req.force_link_speed = rte_cpu_to_le_16(conf->link_speed);
+ enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE;
+ /*
+ * Note, ChiMP FW 20.2.1 and 20.2.2 return an error when we set
+ * any auto mode, even "none".
+ */
+ if (!conf->link_speed) {
+ /* No speeds specified. Enable AutoNeg - all speeds */
+ req.auto_mode =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS;
+ }
+ /* AutoNeg - Advertise speeds specified. */
+ if (conf->auto_link_speed_mask &&
+ !(conf->phy_flags & HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE)) {
+ req.auto_mode =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK;
+ req.auto_link_speed_mask =
+ conf->auto_link_speed_mask;
+ enables |=
+ HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK;
+ }
+
+ req.auto_duplex = conf->duplex;
+ enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX;
+ req.auto_pause = conf->auto_pause;
+ req.force_pause = conf->force_pause;
+ /* Set force_pause if there is no auto or if there is a force */
+ if (req.auto_pause && !req.force_pause)
+ enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE;
+ else
+ enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE;
+
+ req.enables = rte_cpu_to_le_32(enables);
+ } else {
+ req.flags =
+ rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DWN);
+ PMD_DRV_LOG(INFO, "Force Link Down\n");
+ }
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp,
+ struct bnxt_link_info *link_info)
+{
+ int rc = 0;
+ struct hwrm_port_phy_qcfg_input req = {0};
+ struct hwrm_port_phy_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, PORT_PHY_QCFG);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ link_info->phy_link_status = resp->link;
+ link_info->link_up =
+ (link_info->phy_link_status ==
+ HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK) ? 1 : 0;
+ link_info->link_speed = rte_le_to_cpu_16(resp->link_speed);
+ link_info->duplex = resp->duplex_cfg;
+ link_info->pause = resp->pause;
+ link_info->auto_pause = resp->auto_pause;
+ link_info->force_pause = resp->force_pause;
+ link_info->auto_mode = resp->auto_mode;
+ link_info->phy_type = resp->phy_type;
+ link_info->media_type = resp->media_type;
+
+ link_info->support_speeds = rte_le_to_cpu_16(resp->support_speeds);
+ link_info->auto_link_speed = rte_le_to_cpu_16(resp->auto_link_speed);
+ link_info->preemphasis = rte_le_to_cpu_32(resp->preemphasis);
+ link_info->force_link_speed = rte_le_to_cpu_16(resp->force_link_speed);
+ link_info->phy_ver[0] = resp->phy_maj;
+ link_info->phy_ver[1] = resp->phy_min;
+ link_info->phy_ver[2] = resp->phy_bld;
+
+ HWRM_UNLOCK();
+
+ PMD_DRV_LOG(DEBUG, "Link Speed %d\n", link_info->link_speed);
+ PMD_DRV_LOG(DEBUG, "Auto Mode %d\n", link_info->auto_mode);
+ PMD_DRV_LOG(DEBUG, "Support Speeds %x\n", link_info->support_speeds);
+ PMD_DRV_LOG(DEBUG, "Auto Link Speed %x\n", link_info->auto_link_speed);
+ PMD_DRV_LOG(DEBUG, "Auto Link Speed Mask %x\n",
+ link_info->auto_link_speed_mask);
+ PMD_DRV_LOG(DEBUG, "Forced Link Speed %x\n",
+ link_info->force_link_speed);
+
+ 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;
+ int i;
+
+ HWRM_PREP(req, QUEUE_QPORTCFG);
+
+ req.flags = HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX;
+ /* HWRM Version >= 1.9.1 */
+ if (bp->hwrm_spec_code >= HWRM_VERSION_1_9_1)
+ req.drv_qmap_cap =
+ HWRM_QUEUE_QPORTCFG_INPUT_DRV_QMAP_CAP_ENABLED;
+ 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);
+
+ HWRM_UNLOCK();
+
+ if (bp->hwrm_spec_code < HWRM_VERSION_1_9_1) {
+ bp->tx_cosq_id = bp->cos_queue[0].id;
+ } else {
+ /* iterate and find the COSq profile to use for Tx */
+ for (i = 0; i < BNXT_COS_QUEUE_COUNT; i++) {
+ if (bp->cos_queue[i].profile ==
+ HWRM_QUEUE_SERVICE_PROFILE_LOSSY) {
+ bp->tx_cosq_id = bp->cos_queue[i].id;
+ break;
+ }
+ }
+ }
+ PMD_DRV_LOG(DEBUG, "Tx Cos Queue to use: %d\n", bp->tx_cosq_id);
+
+ return rc;
+}
+
+int bnxt_hwrm_ring_alloc(struct bnxt *bp,
+ struct bnxt_ring *ring,
+ uint32_t ring_type, uint32_t map_index,
+ uint32_t stats_ctx_id, uint32_t cmpl_ring_id)
+{
+ int rc = 0;
+ uint32_t enables = 0;
+ struct hwrm_ring_alloc_input req = {.req_type = 0 };
+ struct hwrm_ring_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, RING_ALLOC);
+
+ req.page_tbl_addr = rte_cpu_to_le_64(ring->bd_dma);
+ req.fbo = rte_cpu_to_le_32(0);
+ /* Association of ring index with doorbell index */
+ req.logical_id = rte_cpu_to_le_16(map_index);
+ req.length = rte_cpu_to_le_32(ring->ring_size);
+
+ switch (ring_type) {
+ case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX:
+ req.queue_id = rte_cpu_to_le_16(bp->tx_cosq_id);
+ /* FALLTHROUGH */
+ case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX:
+ req.ring_type = ring_type;
+ req.cmpl_ring_id = rte_cpu_to_le_16(cmpl_ring_id);
+ req.stat_ctx_id = rte_cpu_to_le_16(stats_ctx_id);
+ if (stats_ctx_id != INVALID_STATS_CTX_ID)
+ enables |=
+ HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID;
+ break;
+ case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
+ req.ring_type = ring_type;
+ /*
+ * TODO: Some HWRM versions crash with
+ * HWRM_RING_ALLOC_INPUT_INT_MODE_POLL
+ */
+ req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "hwrm alloc invalid ring type %d\n",
+ ring_type);
+ HWRM_UNLOCK();
+ return -1;
+ }
+ req.enables = rte_cpu_to_le_32(enables);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ if (rc || resp->error_code) {
+ if (rc == 0 && resp->error_code)
+ rc = rte_le_to_cpu_16(resp->error_code);
+ switch (ring_type) {
+ case HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL:
+ PMD_DRV_LOG(ERR,
+ "hwrm_ring_alloc cp failed. rc:%d\n", rc);
+ HWRM_UNLOCK();
+ return rc;
+ case HWRM_RING_FREE_INPUT_RING_TYPE_RX:
+ PMD_DRV_LOG(ERR,
+ "hwrm_ring_alloc rx failed. rc:%d\n", rc);
+ HWRM_UNLOCK();
+ return rc;
+ case HWRM_RING_FREE_INPUT_RING_TYPE_TX:
+ PMD_DRV_LOG(ERR,
+ "hwrm_ring_alloc tx failed. rc:%d\n", rc);
+ HWRM_UNLOCK();
+ return rc;
+ default:
+ PMD_DRV_LOG(ERR, "Invalid ring. rc:%d\n", rc);
+ HWRM_UNLOCK();
+ return rc;
+ }
+ }
+
+ ring->fw_ring_id = rte_le_to_cpu_16(resp->ring_id);
+ HWRM_UNLOCK();
+ return rc;
+}
+
+int bnxt_hwrm_ring_free(struct bnxt *bp,
+ struct bnxt_ring *ring, uint32_t ring_type)
+{
+ int rc;
+ struct hwrm_ring_free_input req = {.req_type = 0 };
+ struct hwrm_ring_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, RING_FREE);
+
+ req.ring_type = ring_type;
+ req.ring_id = rte_cpu_to_le_16(ring->fw_ring_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ if (rc || resp->error_code) {
+ if (rc == 0 && resp->error_code)
+ rc = rte_le_to_cpu_16(resp->error_code);
+ HWRM_UNLOCK();
+
+ switch (ring_type) {
+ case HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL:
+ PMD_DRV_LOG(ERR, "hwrm_ring_free cp failed. rc:%d\n",
+ rc);
+ return rc;
+ case HWRM_RING_FREE_INPUT_RING_TYPE_RX:
+ PMD_DRV_LOG(ERR, "hwrm_ring_free rx failed. rc:%d\n",
+ rc);
+ return rc;
+ case HWRM_RING_FREE_INPUT_RING_TYPE_TX:
+ PMD_DRV_LOG(ERR, "hwrm_ring_free tx failed. rc:%d\n",
+ rc);
+ return rc;
+ default:
+ PMD_DRV_LOG(ERR, "Invalid ring, rc:%d\n", rc);
+ return rc;
+ }
+ }
+ HWRM_UNLOCK();
+ return 0;
+}
+
+int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned int idx)
+{
+ int rc = 0;
+ struct hwrm_ring_grp_alloc_input req = {.req_type = 0 };
+ struct hwrm_ring_grp_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, RING_GRP_ALLOC);
+
+ req.cr = rte_cpu_to_le_16(bp->grp_info[idx].cp_fw_ring_id);
+ req.rr = rte_cpu_to_le_16(bp->grp_info[idx].rx_fw_ring_id);
+ req.ar = rte_cpu_to_le_16(bp->grp_info[idx].ag_fw_ring_id);
+ req.sc = rte_cpu_to_le_16(bp->grp_info[idx].fw_stats_ctx);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ bp->grp_info[idx].fw_grp_id =
+ rte_le_to_cpu_16(resp->ring_group_id);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned int idx)
+{
+ int rc;
+ struct hwrm_ring_grp_free_input req = {.req_type = 0 };
+ struct hwrm_ring_grp_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, RING_GRP_FREE);
+
+ req.ring_group_id = rte_cpu_to_le_16(bp->grp_info[idx].fw_grp_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ bp->grp_info[idx].fw_grp_id = INVALID_HW_RING_ID;
+ return rc;
+}
+
+int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
+{
+ int rc = 0;
+ struct hwrm_stat_ctx_clr_stats_input req = {.req_type = 0 };
+ struct hwrm_stat_ctx_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (cpr->hw_stats_ctx_id == (uint32_t)HWRM_NA_SIGNATURE)
+ return rc;
+
+ HWRM_PREP(req, STAT_CTX_CLR_STATS);
+
+ req.stat_ctx_id = rte_cpu_to_le_16(cpr->hw_stats_ctx_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+ unsigned int idx __rte_unused)
+{
+ int rc;
+ struct hwrm_stat_ctx_alloc_input req = {.req_type = 0 };
+ struct hwrm_stat_ctx_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, STAT_CTX_ALLOC);
+
+ req.update_period_ms = rte_cpu_to_le_32(0);
+
+ req.stats_dma_addr =
+ rte_cpu_to_le_64(cpr->hw_stats_map);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ cpr->hw_stats_ctx_id = rte_le_to_cpu_16(resp->stat_ctx_id);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+ unsigned int idx __rte_unused)
+{
+ int rc;
+ struct hwrm_stat_ctx_free_input req = {.req_type = 0 };
+ struct hwrm_stat_ctx_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, STAT_CTX_FREE);
+
+ req.stat_ctx_id = rte_cpu_to_le_16(cpr->hw_stats_ctx_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0, i, j;
+ struct hwrm_vnic_alloc_input req = { 0 };
+ struct hwrm_vnic_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+
+ /* map ring groups to this vnic */
+ PMD_DRV_LOG(DEBUG, "Alloc VNIC. Start %x, End %x\n",
+ vnic->start_grp_id, vnic->end_grp_id);
+ for (i = vnic->start_grp_id, j = 0; i < vnic->end_grp_id; i++, j++)
+ vnic->fw_grp_ids[j] = bp->grp_info[i].fw_grp_id;
+
+ vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
+ vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
+ vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
+ vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
+ vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+ ETHER_CRC_LEN + VLAN_TAG_SIZE;
+ HWRM_PREP(req, VNIC_ALLOC);
+
+ if (vnic->func_default)
+ req.flags =
+ rte_cpu_to_le_32(HWRM_VNIC_ALLOC_INPUT_FLAGS_DEFAULT);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ vnic->fw_vnic_id = rte_le_to_cpu_16(resp->vnic_id);
+ HWRM_UNLOCK();
+ PMD_DRV_LOG(DEBUG, "VNIC ID %x\n", vnic->fw_vnic_id);
+ return rc;
+}
+
+static int bnxt_hwrm_vnic_plcmodes_qcfg(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic,
+ struct bnxt_plcmodes_cfg *pmode)
+{
+ int rc = 0;
+ struct hwrm_vnic_plcmodes_qcfg_input req = {.req_type = 0 };
+ struct hwrm_vnic_plcmodes_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, VNIC_PLCMODES_QCFG);
+
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ pmode->flags = rte_le_to_cpu_32(resp->flags);
+ /* dflt_vnic bit doesn't exist in the _cfg command */
+ pmode->flags &= ~(HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_DFLT_VNIC);
+ pmode->jumbo_thresh = rte_le_to_cpu_16(resp->jumbo_thresh);
+ pmode->hds_offset = rte_le_to_cpu_16(resp->hds_offset);
+ pmode->hds_threshold = rte_le_to_cpu_16(resp->hds_threshold);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+static int bnxt_hwrm_vnic_plcmodes_cfg(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic,
+ struct bnxt_plcmodes_cfg *pmode)
+{
+ int rc = 0;
+ struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
+ struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, VNIC_PLCMODES_CFG);
+
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+ req.flags = rte_cpu_to_le_32(pmode->flags);
+ req.jumbo_thresh = rte_cpu_to_le_16(pmode->jumbo_thresh);
+ req.hds_offset = rte_cpu_to_le_16(pmode->hds_offset);
+ req.hds_threshold = rte_cpu_to_le_16(pmode->hds_threshold);
+ req.enables = rte_cpu_to_le_32(
+ HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID |
+ HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_OFFSET_VALID |
+ HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID
+ );
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_cfg_input req = {.req_type = 0 };
+ struct hwrm_vnic_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ uint32_t ctx_enable_flag = 0;
+ struct bnxt_plcmodes_cfg pmodes;
+
+ if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
+ PMD_DRV_LOG(DEBUG, "VNIC ID %x\n", vnic->fw_vnic_id);
+ return rc;
+ }
+
+ rc = bnxt_hwrm_vnic_plcmodes_qcfg(bp, vnic, &pmodes);
+ if (rc)
+ return rc;
+
+ HWRM_PREP(req, VNIC_CFG);
+
+ /* Only RSS support for now TBD: COS & LB */
+ req.enables =
+ rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_ENABLES_DFLT_RING_GRP);
+ if (vnic->lb_rule != 0xffff)
+ ctx_enable_flag |= HWRM_VNIC_CFG_INPUT_ENABLES_LB_RULE;
+ if (vnic->cos_rule != 0xffff)
+ ctx_enable_flag |= HWRM_VNIC_CFG_INPUT_ENABLES_COS_RULE;
+ if (vnic->rss_rule != 0xffff) {
+ ctx_enable_flag |= HWRM_VNIC_CFG_INPUT_ENABLES_MRU;
+ ctx_enable_flag |= HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
+ }
+ req.enables |= rte_cpu_to_le_32(ctx_enable_flag);
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+ req.dflt_ring_grp = rte_cpu_to_le_16(vnic->dflt_ring_grp);
+ req.rss_rule = rte_cpu_to_le_16(vnic->rss_rule);
+ req.cos_rule = rte_cpu_to_le_16(vnic->cos_rule);
+ req.lb_rule = rte_cpu_to_le_16(vnic->lb_rule);
+ req.mru = rte_cpu_to_le_16(vnic->mru);
+ if (vnic->func_default)
+ req.flags |=
+ rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT);
+ if (vnic->vlan_strip)
+ req.flags |=
+ rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE);
+ if (vnic->bd_stall)
+ req.flags |=
+ rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE);
+ if (vnic->roce_dual)
+ req.flags |= rte_cpu_to_le_32(
+ HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE);
+ if (vnic->roce_only)
+ req.flags |= rte_cpu_to_le_32(
+ HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE);
+ if (vnic->rss_dflt_cr)
+ req.flags |= rte_cpu_to_le_32(
+ HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ rc = bnxt_hwrm_vnic_plcmodes_cfg(bp, vnic, &pmodes);
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+ int16_t fw_vf_id)
+{
+ int rc = 0;
+ struct hwrm_vnic_qcfg_input req = {.req_type = 0 };
+ struct hwrm_vnic_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
+ PMD_DRV_LOG(DEBUG, "VNIC QCFG ID %d\n", vnic->fw_vnic_id);
+ return rc;
+ }
+ HWRM_PREP(req, VNIC_QCFG);
+
+ req.enables =
+ rte_cpu_to_le_32(HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID);
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+ req.vf_id = rte_cpu_to_le_16(fw_vf_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ vnic->dflt_ring_grp = rte_le_to_cpu_16(resp->dflt_ring_grp);
+ vnic->rss_rule = rte_le_to_cpu_16(resp->rss_rule);
+ vnic->cos_rule = rte_le_to_cpu_16(resp->cos_rule);
+ vnic->lb_rule = rte_le_to_cpu_16(resp->lb_rule);
+ vnic->mru = rte_le_to_cpu_16(resp->mru);
+ vnic->func_default = rte_le_to_cpu_32(
+ resp->flags) & HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT;
+ vnic->vlan_strip = rte_le_to_cpu_32(resp->flags) &
+ HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE;
+ vnic->bd_stall = rte_le_to_cpu_32(resp->flags) &
+ HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE;
+ vnic->roce_dual = rte_le_to_cpu_32(resp->flags) &
+ HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE;
+ vnic->roce_only = rte_le_to_cpu_32(resp->flags) &
+ HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE;
+ vnic->rss_dflt_cr = rte_le_to_cpu_32(resp->flags) &
+ HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE;
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_rss_cos_lb_ctx_alloc_input req = {.req_type = 0 };
+ struct hwrm_vnic_rss_cos_lb_ctx_alloc_output *resp =
+ bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, VNIC_RSS_COS_LB_CTX_ALLOC);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ vnic->rss_rule = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
+ HWRM_UNLOCK();
+ PMD_DRV_LOG(DEBUG, "VNIC RSS Rule %x\n", vnic->rss_rule);
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_rss_cos_lb_ctx_free_input req = {.req_type = 0 };
+ struct hwrm_vnic_rss_cos_lb_ctx_free_output *resp =
+ bp->hwrm_cmd_resp_addr;
+
+ if (vnic->rss_rule == 0xffff) {
+ PMD_DRV_LOG(DEBUG, "VNIC RSS Rule %x\n", vnic->rss_rule);
+ return rc;
+ }
+ HWRM_PREP(req, VNIC_RSS_COS_LB_CTX_FREE);
+
+ req.rss_cos_lb_ctx_id = rte_cpu_to_le_16(vnic->rss_rule);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ vnic->rss_rule = INVALID_HW_RING_ID;
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_free_input req = {.req_type = 0 };
+ struct hwrm_vnic_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
+ PMD_DRV_LOG(DEBUG, "VNIC FREE ID %x\n", vnic->fw_vnic_id);
+ return rc;
+ }
+
+ HWRM_PREP(req, VNIC_FREE);
+
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ vnic->fw_vnic_id = INVALID_HW_RING_ID;
+ return rc;
+}
+
+int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_rss_cfg_input req = {.req_type = 0 };
+ struct hwrm_vnic_rss_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, VNIC_RSS_CFG);
+
+ req.hash_type = rte_cpu_to_le_32(vnic->hash_type);
+ req.hash_mode_flags = vnic->hash_mode;
+
+ req.ring_grp_tbl_addr =
+ rte_cpu_to_le_64(vnic->rss_table_dma_addr);
+ req.hash_key_tbl_addr =
+ rte_cpu_to_le_64(vnic->rss_hash_key_dma_addr);
+ req.rss_ctx_idx = rte_cpu_to_le_16(vnic->rss_rule);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
+ struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ uint16_t size;
+
+ if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
+ PMD_DRV_LOG(DEBUG, "VNIC ID %x\n", vnic->fw_vnic_id);
+ return rc;
+ }
+
+ HWRM_PREP(req, VNIC_PLCMODES_CFG);
+
+ req.flags = rte_cpu_to_le_32(
+ HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
+
+ req.enables = rte_cpu_to_le_32(
+ HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
+
+ size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
+ size -= RTE_PKTMBUF_HEADROOM;
+
+ req.jumbo_thresh = rte_cpu_to_le_16(size);
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic, bool enable)
+{
+ int rc = 0;
+ struct hwrm_vnic_tpa_cfg_input req = {.req_type = 0 };
+ struct hwrm_vnic_tpa_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, VNIC_TPA_CFG);
+
+ if (enable) {
+ req.enables = rte_cpu_to_le_32(
+ HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS |
+ HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS |
+ HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN);
+ req.flags = rte_cpu_to_le_32(
+ HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA |
+ HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA |
+ HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE |
+ HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO |
+ HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN |
+ HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ);
+ req.max_agg_segs = rte_cpu_to_le_16(5);
+ req.max_aggs =
+ rte_cpu_to_le_16(HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX);
+ req.min_agg_len = rte_cpu_to_le_32(512);
+ }
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
+{
+ struct hwrm_func_cfg_input req = {0};
+ struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc;
+
+ req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+ req.enables = rte_cpu_to_le_32(
+ HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+ memcpy(req.dflt_mac_addr, mac_addr, sizeof(req.dflt_mac_addr));
+ req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+
+ HWRM_PREP(req, FUNC_CFG);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ bp->pf.vf_info[vf].random_mac = false;
+
+ return rc;
+}
+
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+ uint64_t *dropped)
+{
+ int rc = 0;
+ struct hwrm_func_qstats_input req = {.req_type = 0};
+ struct hwrm_func_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_QSTATS);
+
+ req.fid = rte_cpu_to_le_16(fid);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ if (dropped)
+ *dropped = rte_le_to_cpu_64(resp->tx_drop_pkts);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
+ struct rte_eth_stats *stats)
+{
+ int rc = 0;
+ struct hwrm_func_qstats_input req = {.req_type = 0};
+ struct hwrm_func_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_QSTATS);
+
+ req.fid = rte_cpu_to_le_16(fid);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ stats->ipackets = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+ stats->ipackets += rte_le_to_cpu_64(resp->rx_mcast_pkts);
+ stats->ipackets += rte_le_to_cpu_64(resp->rx_bcast_pkts);
+ stats->ibytes = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+ stats->ibytes += rte_le_to_cpu_64(resp->rx_mcast_bytes);
+ stats->ibytes += rte_le_to_cpu_64(resp->rx_bcast_bytes);
+
+ stats->opackets = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+ stats->opackets += rte_le_to_cpu_64(resp->tx_mcast_pkts);
+ stats->opackets += rte_le_to_cpu_64(resp->tx_bcast_pkts);
+ stats->obytes = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+ stats->obytes += rte_le_to_cpu_64(resp->tx_mcast_bytes);
+ stats->obytes += rte_le_to_cpu_64(resp->tx_bcast_bytes);
+
+ stats->imissed = rte_le_to_cpu_64(resp->rx_discard_pkts);
+ stats->ierrors = rte_le_to_cpu_64(resp->rx_drop_pkts);
+ stats->oerrors = rte_le_to_cpu_64(resp->tx_discard_pkts);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid)
+{
+ int rc = 0;
+ struct hwrm_func_clr_stats_input req = {.req_type = 0};
+ struct hwrm_func_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_CLR_STATS);
+
+ req.fid = rte_cpu_to_le_16(fid);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+/*
+ * HWRM utility functions
+ */
+
+int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp)
+{
+ unsigned int i;
+ int rc = 0;
+
+ for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq;
+ struct bnxt_rx_queue *rxq;
+ struct bnxt_cp_ring_info *cpr;
+
+ if (i >= bp->rx_cp_nr_rings) {
+ txq = bp->tx_queues[i - bp->rx_cp_nr_rings];
+ cpr = txq->cp_ring;
+ } else {
+ rxq = bp->rx_queues[i];
+ cpr = rxq->cp_ring;
+ }
+
+ rc = bnxt_hwrm_stat_clear(bp, cpr);
+ if (rc)
+ return rc;
+ }
+ return 0;
+}
+
+int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp)
+{
+ int rc;
+ unsigned int i;
+ struct bnxt_cp_ring_info *cpr;
+
+ for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
+
+ if (i >= bp->rx_cp_nr_rings) {
+ cpr = bp->tx_queues[i - bp->rx_cp_nr_rings]->cp_ring;
+ } else {
+ cpr = bp->rx_queues[i]->cp_ring;
+ bp->grp_info[i].fw_stats_ctx = -1;
+ }
+ if (cpr->hw_stats_ctx_id != HWRM_NA_SIGNATURE) {
+ rc = bnxt_hwrm_stat_ctx_free(bp, cpr, i);
+ cpr->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
+ if (rc)
+ return rc;
+ }
+ }
+ return 0;
+}
+
+int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
+{
+ unsigned int i;
+ int rc = 0;
+
+ for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq;
+ struct bnxt_rx_queue *rxq;
+ struct bnxt_cp_ring_info *cpr;
+
+ if (i >= bp->rx_cp_nr_rings) {
+ txq = bp->tx_queues[i - bp->rx_cp_nr_rings];
+ cpr = txq->cp_ring;
+ } else {
+ rxq = bp->rx_queues[i];
+ cpr = rxq->cp_ring;
+ }
+
+ rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, i);
+
+ if (rc)
+ return rc;
+ }
+ return rc;
+}
+
+int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp)
+{
+ uint16_t idx;
+ uint32_t rc = 0;
+
+ for (idx = 0; idx < bp->rx_cp_nr_rings; idx++) {
+
+ if (bp->grp_info[idx].fw_grp_id == INVALID_HW_RING_ID)
+ continue;
+
+ rc = bnxt_hwrm_ring_grp_free(bp, idx);
+
+ if (rc)
+ return rc;
+ }
+ return rc;
+}
+
+static void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
+{
+ struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
+
+ bnxt_hwrm_ring_free(bp, cp_ring,
+ HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL);
+ cp_ring->fw_ring_id = INVALID_HW_RING_ID;
+ memset(cpr->cp_desc_ring, 0, cpr->cp_ring_struct->ring_size *
+ sizeof(*cpr->cp_desc_ring));
+ cpr->cp_raw_cons = 0;
+}
+
+void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index)
+{
+ struct bnxt_rx_queue *rxq = bp->rx_queues[queue_index];
+ struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+ struct bnxt_ring *ring = rxr->rx_ring_struct;
+ struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+
+ if (ring->fw_ring_id != INVALID_HW_RING_ID) {
+ bnxt_hwrm_ring_free(bp, ring,
+ HWRM_RING_FREE_INPUT_RING_TYPE_RX);
+ ring->fw_ring_id = INVALID_HW_RING_ID;
+ bp->grp_info[queue_index].rx_fw_ring_id = INVALID_HW_RING_ID;
+ memset(rxr->rx_desc_ring, 0,
+ rxr->rx_ring_struct->ring_size *
+ sizeof(*rxr->rx_desc_ring));
+ memset(rxr->rx_buf_ring, 0,
+ rxr->rx_ring_struct->ring_size *
+ sizeof(*rxr->rx_buf_ring));
+ rxr->rx_prod = 0;
+ }
+ ring = rxr->ag_ring_struct;
+ if (ring->fw_ring_id != INVALID_HW_RING_ID) {
+ bnxt_hwrm_ring_free(bp, ring,
+ HWRM_RING_FREE_INPUT_RING_TYPE_RX);
+ ring->fw_ring_id = INVALID_HW_RING_ID;
+ memset(rxr->ag_buf_ring, 0,
+ rxr->ag_ring_struct->ring_size *
+ sizeof(*rxr->ag_buf_ring));
+ rxr->ag_prod = 0;
+ bp->grp_info[queue_index].ag_fw_ring_id = INVALID_HW_RING_ID;
+ }
+ if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID)
+ bnxt_free_cp_ring(bp, cpr);
+
+ bp->grp_info[queue_index].cp_fw_ring_id = INVALID_HW_RING_ID;
+}
+
+int bnxt_free_all_hwrm_rings(struct bnxt *bp)
+{
+ unsigned int i;
+
+ for (i = 0; i < bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+ struct bnxt_tx_ring_info *txr = txq->tx_ring;
+ struct bnxt_ring *ring = txr->tx_ring_struct;
+ struct bnxt_cp_ring_info *cpr = txq->cp_ring;
+
+ if (ring->fw_ring_id != INVALID_HW_RING_ID) {
+ bnxt_hwrm_ring_free(bp, ring,
+ HWRM_RING_FREE_INPUT_RING_TYPE_TX);
+ ring->fw_ring_id = INVALID_HW_RING_ID;
+ memset(txr->tx_desc_ring, 0,
+ txr->tx_ring_struct->ring_size *
+ sizeof(*txr->tx_desc_ring));
+ memset(txr->tx_buf_ring, 0,
+ txr->tx_ring_struct->ring_size *
+ sizeof(*txr->tx_buf_ring));
+ txr->tx_prod = 0;
+ txr->tx_cons = 0;
+ }
+ if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
+ bnxt_free_cp_ring(bp, cpr);
+ cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+ }
+ }
+
+ for (i = 0; i < bp->rx_cp_nr_rings; i++)
+ bnxt_free_hwrm_rx_ring(bp, i);
+
+ return 0;
+}
+
+int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp)
+{
+ uint16_t i;
+ uint32_t rc = 0;
+
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ rc = bnxt_hwrm_ring_grp_alloc(bp, i);
+ if (rc)
+ return rc;
+ }
+ return rc;
+}
+
+void bnxt_free_hwrm_resources(struct bnxt *bp)
+{
+ /* Release memzone */
+ rte_free(bp->hwrm_cmd_resp_addr);
+ rte_free(bp->hwrm_short_cmd_req_addr);
+ bp->hwrm_cmd_resp_addr = NULL;
+ bp->hwrm_short_cmd_req_addr = NULL;
+ bp->hwrm_cmd_resp_dma_addr = 0;
+ bp->hwrm_short_cmd_req_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_resp_len = HWRM_MAX_RESP_LEN;
+ bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0);
+ rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
+ if (bp->hwrm_cmd_resp_addr == NULL)
+ return -ENOMEM;
+ bp->hwrm_cmd_resp_dma_addr =
+ rte_mem_virt2iova(bp->hwrm_cmd_resp_addr);
+ if (bp->hwrm_cmd_resp_dma_addr == 0) {
+ PMD_DRV_LOG(ERR,
+ "unable to map response address to physical memory\n");
+ return -ENOMEM;
+ }
+ rte_spinlock_init(&bp->hwrm_lock);
+
+ return 0;
+}
+
+int bnxt_clear_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ struct bnxt_filter_info *filter;
+ int rc = 0;
+
+ STAILQ_FOREACH(filter, &vnic->filter, next) {
+ if (filter->filter_type == HWRM_CFA_EM_FILTER)
+ rc = bnxt_hwrm_clear_em_filter(bp, filter);
+ else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
+ rc = bnxt_hwrm_clear_ntuple_filter(bp, filter);
+ else
+ rc = bnxt_hwrm_clear_l2_filter(bp, filter);
+ STAILQ_REMOVE(&vnic->filter, filter, bnxt_filter_info, next);
+ //if (rc)
+ //break;
+ }
+ return rc;
+}
+
+static int
+bnxt_clear_hwrm_vnic_flows(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ struct bnxt_filter_info *filter;
+ struct rte_flow *flow;
+ int rc = 0;
+
+ STAILQ_FOREACH(flow, &vnic->flow_list, next) {
+ filter = flow->filter;
+ PMD_DRV_LOG(ERR, "filter type %d\n", filter->filter_type);
+ if (filter->filter_type == HWRM_CFA_EM_FILTER)
+ rc = bnxt_hwrm_clear_em_filter(bp, filter);
+ else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
+ rc = bnxt_hwrm_clear_ntuple_filter(bp, filter);
+ else
+ rc = bnxt_hwrm_clear_l2_filter(bp, filter);
+
+ STAILQ_REMOVE(&vnic->flow_list, flow, rte_flow, next);
+ rte_free(flow);
+ //if (rc)
+ //break;
+ }
+ return rc;
+}
+
+int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ struct bnxt_filter_info *filter;
+ int rc = 0;
+
+ STAILQ_FOREACH(filter, &vnic->filter, next) {
+ if (filter->filter_type == HWRM_CFA_EM_FILTER)
+ rc = bnxt_hwrm_set_em_filter(bp, filter->dst_id,
+ filter);
+ else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
+ rc = bnxt_hwrm_set_ntuple_filter(bp, filter->dst_id,
+ filter);
+ else
+ rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id,
+ filter);
+ if (rc)
+ break;
+ }
+ return rc;
+}
+
+void bnxt_free_tunnel_ports(struct bnxt *bp)
+{
+ if (bp->vxlan_port_cnt)
+ bnxt_hwrm_tunnel_dst_port_free(bp, bp->vxlan_fw_dst_port_id,
+ HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN);
+ bp->vxlan_port = 0;
+ if (bp->geneve_port_cnt)
+ bnxt_hwrm_tunnel_dst_port_free(bp, bp->geneve_fw_dst_port_id,
+ HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE);
+ bp->geneve_port = 0;
+}
+
+void bnxt_free_all_hwrm_resources(struct bnxt *bp)
+{
+ int i;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ /*
+ * Cleanup VNICs in reverse order, to make sure the L2 filter
+ * from vnic0 is last to be cleaned up.
+ */
+ for (i = bp->nr_vnics - 1; i >= 0; i--) {
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+ bnxt_clear_hwrm_vnic_flows(bp, vnic);
+
+ bnxt_clear_hwrm_vnic_filters(bp, vnic);
+
+ bnxt_hwrm_vnic_ctx_free(bp, vnic);
+
+ bnxt_hwrm_vnic_tpa_cfg(bp, vnic, false);
+
+ bnxt_hwrm_vnic_free(bp, vnic);
+
+ rte_free(vnic->fw_grp_ids);
+ }
+ /* Ring resources */
+ bnxt_free_all_hwrm_rings(bp);
+ bnxt_free_all_hwrm_ring_grps(bp);
+ bnxt_free_all_hwrm_stat_ctxs(bp);
+ bnxt_free_tunnel_ports(bp);
+}
+
+static uint16_t bnxt_parse_eth_link_duplex(uint32_t conf_link_speed)
+{
+ uint8_t hw_link_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH;
+
+ if ((conf_link_speed & ETH_LINK_SPEED_FIXED) == ETH_LINK_SPEED_AUTONEG)
+ return HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH;
+
+ switch (conf_link_speed) {
+ case ETH_LINK_SPEED_10M_HD:
+ case ETH_LINK_SPEED_100M_HD:
+ /* FALLTHROUGH */
+ return HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF;
+ }
+ return hw_link_duplex;
+}
+
+static uint16_t bnxt_check_eth_link_autoneg(uint32_t conf_link)
+{
+ return (conf_link & ETH_LINK_SPEED_FIXED) ? 0 : 1;
+}
+
+static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed)
+{
+ uint16_t eth_link_speed = 0;
+
+ if (conf_link_speed == ETH_LINK_SPEED_AUTONEG)
+ return ETH_LINK_SPEED_AUTONEG;
+
+ switch (conf_link_speed & ~ETH_LINK_SPEED_FIXED) {
+ case ETH_LINK_SPEED_100M:
+ case ETH_LINK_SPEED_100M_HD:
+ /* FALLTHROUGH */
+ eth_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100MB;
+ break;
+ case ETH_LINK_SPEED_1G:
+ eth_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB;
+ break;
+ case ETH_LINK_SPEED_2_5G:
+ eth_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB;
+ break;
+ case ETH_LINK_SPEED_10G:
+ eth_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB;
+ break;
+ case ETH_LINK_SPEED_20G:
+ eth_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB;
+ break;
+ case ETH_LINK_SPEED_25G:
+ eth_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB;
+ break;
+ case ETH_LINK_SPEED_40G:
+ eth_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB;
+ break;
+ case ETH_LINK_SPEED_50G:
+ eth_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB;
+ break;
+ case ETH_LINK_SPEED_100G:
+ eth_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB;
+ break;
+ default:
+ PMD_DRV_LOG(ERR,
+ "Unsupported link speed %d; default to AUTO\n",
+ conf_link_speed);
+ break;
+ }
+ return eth_link_speed;
+}
+
+#define BNXT_SUPPORTED_SPEEDS (ETH_LINK_SPEED_100M | ETH_LINK_SPEED_100M_HD | \
+ ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G | \
+ ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G | ETH_LINK_SPEED_25G | \
+ ETH_LINK_SPEED_40G | ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G)
+
+static int bnxt_valid_link_speed(uint32_t link_speed, uint16_t port_id)
+{
+ uint32_t one_speed;
+
+ if (link_speed == ETH_LINK_SPEED_AUTONEG)
+ return 0;
+
+ if (link_speed & ETH_LINK_SPEED_FIXED) {
+ one_speed = link_speed & ~ETH_LINK_SPEED_FIXED;
+
+ if (one_speed & (one_speed - 1)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid advertised speeds (%u) for port %u\n",
+ link_speed, port_id);
+ return -EINVAL;
+ }
+ if ((one_speed & BNXT_SUPPORTED_SPEEDS) != one_speed) {
+ PMD_DRV_LOG(ERR,
+ "Unsupported advertised speed (%u) for port %u\n",
+ link_speed, port_id);
+ return -EINVAL;
+ }
+ } else {
+ if (!(link_speed & BNXT_SUPPORTED_SPEEDS)) {
+ PMD_DRV_LOG(ERR,
+ "Unsupported advertised speeds (%u) for port %u\n",
+ link_speed, port_id);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static uint16_t
+bnxt_parse_eth_link_speed_mask(struct bnxt *bp, uint32_t link_speed)
+{
+ uint16_t ret = 0;
+
+ if (link_speed == ETH_LINK_SPEED_AUTONEG) {
+ if (bp->link_info.support_speeds)
+ return bp->link_info.support_speeds;
+ link_speed = BNXT_SUPPORTED_SPEEDS;
+ }
+
+ if (link_speed & ETH_LINK_SPEED_100M)
+ ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB;
+ if (link_speed & ETH_LINK_SPEED_100M_HD)
+ ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB;
+ if (link_speed & ETH_LINK_SPEED_1G)
+ ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB;
+ if (link_speed & ETH_LINK_SPEED_2_5G)
+ ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2_5GB;
+ if (link_speed & ETH_LINK_SPEED_10G)
+ ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB;
+ if (link_speed & ETH_LINK_SPEED_20G)
+ ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB;
+ if (link_speed & ETH_LINK_SPEED_25G)
+ ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB;
+ if (link_speed & ETH_LINK_SPEED_40G)
+ ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB;
+ if (link_speed & ETH_LINK_SPEED_50G)
+ ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB;
+ if (link_speed & ETH_LINK_SPEED_100G)
+ ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100GB;
+ return ret;
+}
+
+static uint32_t bnxt_parse_hw_link_speed(uint16_t hw_link_speed)
+{
+ uint32_t eth_link_speed = ETH_SPEED_NUM_NONE;
+
+ switch (hw_link_speed) {
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB:
+ eth_link_speed = ETH_SPEED_NUM_100M;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB:
+ eth_link_speed = ETH_SPEED_NUM_1G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB:
+ eth_link_speed = ETH_SPEED_NUM_2_5G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB:
+ eth_link_speed = ETH_SPEED_NUM_10G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB:
+ eth_link_speed = ETH_SPEED_NUM_20G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB:
+ eth_link_speed = ETH_SPEED_NUM_25G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB:
+ eth_link_speed = ETH_SPEED_NUM_40G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB:
+ eth_link_speed = ETH_SPEED_NUM_50G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB:
+ eth_link_speed = ETH_SPEED_NUM_100G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB:
+ default:
+ PMD_DRV_LOG(ERR, "HWRM link speed %d not defined\n",
+ hw_link_speed);
+ break;
+ }
+ return eth_link_speed;
+}
+
+static uint16_t bnxt_parse_hw_link_duplex(uint16_t hw_link_duplex)
+{
+ uint16_t eth_link_duplex = ETH_LINK_FULL_DUPLEX;
+
+ switch (hw_link_duplex) {
+ case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH:
+ case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL:
+ /* FALLTHROUGH */
+ eth_link_duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF:
+ eth_link_duplex = ETH_LINK_HALF_DUPLEX;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "HWRM link duplex %d not defined\n",
+ hw_link_duplex);
+ break;
+ }
+ return eth_link_duplex;
+}
+
+int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link)
+{
+ int rc = 0;
+ struct bnxt_link_info *link_info = &bp->link_info;
+
+ rc = bnxt_hwrm_port_phy_qcfg(bp, link_info);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "Get link config failed with rc %d\n", rc);
+ goto exit;
+ }
+ if (link_info->link_speed)
+ link->link_speed =
+ bnxt_parse_hw_link_speed(link_info->link_speed);
+ else
+ link->link_speed = ETH_SPEED_NUM_NONE;
+ link->link_duplex = bnxt_parse_hw_link_duplex(link_info->duplex);
+ link->link_status = link_info->link_up;
+ link->link_autoneg = link_info->auto_mode ==
+ HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE ?
+ ETH_LINK_FIXED : ETH_LINK_AUTONEG;
+exit:
+ return rc;
+}
+
+int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
+{
+ int rc = 0;
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ struct bnxt_link_info link_req;
+ uint16_t speed, autoneg;
+
+ if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp))
+ return 0;
+
+ rc = bnxt_valid_link_speed(dev_conf->link_speeds,
+ bp->eth_dev->data->port_id);
+ if (rc)
+ goto error;
+
+ memset(&link_req, 0, sizeof(link_req));
+ link_req.link_up = link_up;
+ if (!link_up)
+ goto port_phy_cfg;
+
+ autoneg = bnxt_check_eth_link_autoneg(dev_conf->link_speeds);
+ speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds);
+ link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY;
+ /* Autoneg can be done only when the FW allows */
+ if (autoneg == 1 && !(bp->link_info.auto_link_speed ||
+ bp->link_info.force_link_speed)) {
+ link_req.phy_flags |=
+ HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG;
+ link_req.auto_link_speed_mask =
+ bnxt_parse_eth_link_speed_mask(bp,
+ dev_conf->link_speeds);
+ } else {
+ if (bp->link_info.phy_type ==
+ HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET ||
+ bp->link_info.phy_type ==
+ HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE ||
+ bp->link_info.media_type ==
+ HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP) {
+ PMD_DRV_LOG(ERR, "10GBase-T devices must autoneg\n");
+ return -EINVAL;
+ }
+
+ link_req.phy_flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE;
+ /* If user wants a particular speed try that first. */
+ if (speed)
+ link_req.link_speed = speed;
+ else if (bp->link_info.force_link_speed)
+ link_req.link_speed = bp->link_info.force_link_speed;
+ else
+ link_req.link_speed = bp->link_info.auto_link_speed;
+ }
+ link_req.duplex = bnxt_parse_eth_link_duplex(dev_conf->link_speeds);
+ link_req.auto_pause = bp->link_info.auto_pause;
+ link_req.force_pause = bp->link_info.force_pause;
+
+port_phy_cfg:
+ rc = bnxt_hwrm_port_phy_cfg(bp, &link_req);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "Set link config failed with rc %d\n", rc);
+ }
+
+error:
+ return rc;
+}
+
+/* JIRA 22088 */
+int bnxt_hwrm_func_qcfg(struct bnxt *bp)
+{
+ struct hwrm_func_qcfg_input req = {0};
+ struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+ uint16_t flags;
+ int rc = 0;
+
+ HWRM_PREP(req, FUNC_QCFG);
+ req.fid = rte_cpu_to_le_16(0xffff);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ /* Hard Coded.. 0xfff VLAN ID mask */
+ bp->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff;
+ flags = rte_le_to_cpu_16(resp->flags);
+ if (BNXT_PF(bp) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_HOST))
+ bp->flags |= BNXT_FLAG_MULTI_HOST;
+
+ switch (resp->port_partition_type) {
+ case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0:
+ case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5:
+ case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0:
+ /* FALLTHROUGH */
+ bp->port_partition_type = resp->port_partition_type;
+ break;
+ default:
+ bp->port_partition_type = 0;
+ break;
+ }
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+static void copy_func_cfg_to_qcaps(struct hwrm_func_cfg_input *fcfg,
+ struct hwrm_func_qcaps_output *qcaps)
+{
+ qcaps->max_rsscos_ctx = fcfg->num_rsscos_ctxs;
+ memcpy(qcaps->mac_address, fcfg->dflt_mac_addr,
+ sizeof(qcaps->mac_address));
+ qcaps->max_l2_ctxs = fcfg->num_l2_ctxs;
+ qcaps->max_rx_rings = fcfg->num_rx_rings;
+ qcaps->max_tx_rings = fcfg->num_tx_rings;
+ qcaps->max_cmpl_rings = fcfg->num_cmpl_rings;
+ qcaps->max_stat_ctx = fcfg->num_stat_ctxs;
+ qcaps->max_vfs = 0;
+ qcaps->first_vf_id = 0;
+ qcaps->max_vnics = fcfg->num_vnics;
+ qcaps->max_decap_records = 0;
+ qcaps->max_encap_records = 0;
+ qcaps->max_tx_wm_flows = 0;
+ qcaps->max_tx_em_flows = 0;
+ qcaps->max_rx_wm_flows = 0;
+ qcaps->max_rx_em_flows = 0;
+ qcaps->max_flow_id = 0;
+ qcaps->max_mcast_filters = fcfg->num_mcast_filters;
+ qcaps->max_sp_tx_rings = 0;
+ qcaps->max_hw_ring_grps = fcfg->num_hw_ring_grps;
+}
+
+static int bnxt_hwrm_pf_func_cfg(struct bnxt *bp, int tx_rings)
+{
+ struct hwrm_func_cfg_input req = {0};
+ struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc;
+
+ req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU |
+ HWRM_FUNC_CFG_INPUT_ENABLES_MRU |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
+ req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
+ req.mtu = rte_cpu_to_le_16(BNXT_MAX_MTU);
+ req.mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+ ETHER_CRC_LEN + VLAN_TAG_SIZE *
+ BNXT_NUM_VLANS);
+ req.num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx);
+ req.num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx);
+ req.num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings);
+ req.num_tx_rings = rte_cpu_to_le_16(tx_rings);
+ req.num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings);
+ req.num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx);
+ req.num_vnics = rte_cpu_to_le_16(bp->max_vnics);
+ req.num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps);
+ req.fid = rte_cpu_to_le_16(0xffff);
+
+ HWRM_PREP(req, FUNC_CFG);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+static void populate_vf_func_cfg_req(struct bnxt *bp,
+ struct hwrm_func_cfg_input *req,
+ int num_vfs)
+{
+ req->enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU |
+ HWRM_FUNC_CFG_INPUT_ENABLES_MRU |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
+ HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
+
+ req->mtu = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+ ETHER_CRC_LEN + VLAN_TAG_SIZE *
+ BNXT_NUM_VLANS);
+ req->mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+ ETHER_CRC_LEN + VLAN_TAG_SIZE *
+ BNXT_NUM_VLANS);
+ req->num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx /
+ (num_vfs + 1));
+ req->num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx / (num_vfs + 1));
+ req->num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings /
+ (num_vfs + 1));
+ req->num_tx_rings = rte_cpu_to_le_16(bp->max_tx_rings / (num_vfs + 1));
+ req->num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings / (num_vfs + 1));
+ req->num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx / (num_vfs + 1));
+ /* TODO: For now, do not support VMDq/RFS on VFs. */
+ req->num_vnics = rte_cpu_to_le_16(1);
+ req->num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps /
+ (num_vfs + 1));
+}
+
+static void add_random_mac_if_needed(struct bnxt *bp,
+ struct hwrm_func_cfg_input *cfg_req,
+ int vf)
+{
+ struct ether_addr mac;
+
+ if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf, &mac))
+ return;
+
+ if (memcmp(mac.addr_bytes, "\x00\x00\x00\x00\x00", 6) == 0) {
+ cfg_req->enables |=
+ rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+ eth_random_addr(cfg_req->dflt_mac_addr);
+ bp->pf.vf_info[vf].random_mac = true;
+ } else {
+ memcpy(cfg_req->dflt_mac_addr, mac.addr_bytes, ETHER_ADDR_LEN);
+ }
+}
+
+static void reserve_resources_from_vf(struct bnxt *bp,
+ struct hwrm_func_cfg_input *cfg_req,
+ int vf)
+{
+ struct hwrm_func_qcaps_input req = {0};
+ struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc;
+
+ /* Get the actual allocated values now */
+ HWRM_PREP(req, FUNC_QCAPS);
+ req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ if (rc) {
+ PMD_DRV_LOG(ERR, "hwrm_func_qcaps failed rc:%d\n", rc);
+ copy_func_cfg_to_qcaps(cfg_req, resp);
+ } else if (resp->error_code) {
+ rc = rte_le_to_cpu_16(resp->error_code);
+ PMD_DRV_LOG(ERR, "hwrm_func_qcaps error %d\n", rc);
+ copy_func_cfg_to_qcaps(cfg_req, resp);
+ }
+
+ bp->max_rsscos_ctx -= rte_le_to_cpu_16(resp->max_rsscos_ctx);
+ bp->max_stat_ctx -= rte_le_to_cpu_16(resp->max_stat_ctx);
+ bp->max_cp_rings -= rte_le_to_cpu_16(resp->max_cmpl_rings);
+ bp->max_tx_rings -= rte_le_to_cpu_16(resp->max_tx_rings);
+ bp->max_rx_rings -= rte_le_to_cpu_16(resp->max_rx_rings);
+ bp->max_l2_ctx -= rte_le_to_cpu_16(resp->max_l2_ctxs);
+ /*
+ * TODO: While not supporting VMDq with VFs, max_vnics is always
+ * forced to 1 in this case
+ */
+ //bp->max_vnics -= rte_le_to_cpu_16(esp->max_vnics);
+ bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps);
+
+ HWRM_UNLOCK();
+}
+
+int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf)
+{
+ struct hwrm_func_qcfg_input req = {0};
+ struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc;
+
+ /* Check for zero MAC address */
+ HWRM_PREP(req, FUNC_QCFG);
+ req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+ if (rc) {
+ PMD_DRV_LOG(ERR, "hwrm_func_qcfg failed rc:%d\n", rc);
+ return -1;
+ } else if (resp->error_code) {
+ rc = rte_le_to_cpu_16(resp->error_code);
+ PMD_DRV_LOG(ERR, "hwrm_func_qcfg error %d\n", rc);
+ return -1;
+ }
+ rc = rte_le_to_cpu_16(resp->vlan);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+static int update_pf_resource_max(struct bnxt *bp)
+{
+ struct hwrm_func_qcfg_input req = {0};
+ struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc;
+
+ /* And copy the allocated numbers into the pf struct */
+ HWRM_PREP(req, FUNC_QCFG);
+ req.fid = rte_cpu_to_le_16(0xffff);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+ HWRM_CHECK_RESULT();
+
+ /* Only TX ring value reflects actual allocation? TODO */
+ bp->max_tx_rings = rte_le_to_cpu_16(resp->alloc_tx_rings);
+ bp->pf.evb_mode = resp->evb_mode;
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_allocate_pf_only(struct bnxt *bp)
+{
+ int rc;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR, "Attempt to allcoate VFs on a VF!\n");
+ return -1;
+ }
+
+ rc = bnxt_hwrm_func_qcaps(bp);
+ if (rc)
+ return rc;
+
+ bp->pf.func_cfg_flags &=
+ ~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE |
+ HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE);
+ bp->pf.func_cfg_flags |=
+ HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE;
+ rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings);
+ return rc;
+}
+
+int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
+{
+ struct hwrm_func_cfg_input req = {0};
+ struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ int i;
+ size_t sz;
+ int rc = 0;
+ size_t req_buf_sz;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR, "Attempt to allcoate VFs on a VF!\n");
+ return -1;
+ }
+
+ rc = bnxt_hwrm_func_qcaps(bp);
+
+ if (rc)
+ return rc;
+
+ bp->pf.active_vfs = num_vfs;
+
+ /*
+ * First, configure the PF to only use one TX ring. This ensures that
+ * there are enough rings for all VFs.
+ *
+ * If we don't do this, when we call func_alloc() later, we will lock
+ * extra rings to the PF that won't be available during func_cfg() of
+ * the VFs.
+ *
+ * This has been fixed with firmware versions above 20.6.54
+ */
+ bp->pf.func_cfg_flags &=
+ ~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE |
+ HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE);
+ bp->pf.func_cfg_flags |=
+ HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE;
+ rc = bnxt_hwrm_pf_func_cfg(bp, 1);
+ if (rc)
+ return rc;
+
+ /*
+ * Now, create and register a buffer to hold forwarded VF requests
+ */
+ req_buf_sz = num_vfs * HWRM_MAX_REQ_LEN;
+ bp->pf.vf_req_buf = rte_malloc("bnxt_vf_fwd", req_buf_sz,
+ page_roundup(num_vfs * HWRM_MAX_REQ_LEN));
+ if (bp->pf.vf_req_buf == NULL) {
+ rc = -ENOMEM;
+ goto error_free;
+ }
+ for (sz = 0; sz < req_buf_sz; sz += getpagesize())
+ rte_mem_lock_page(((char *)bp->pf.vf_req_buf) + sz);
+ for (i = 0; i < num_vfs; i++)
+ bp->pf.vf_info[i].req_buf = ((char *)bp->pf.vf_req_buf) +
+ (i * HWRM_MAX_REQ_LEN);
+
+ rc = bnxt_hwrm_func_buf_rgtr(bp);
+ if (rc)
+ goto error_free;
+
+ populate_vf_func_cfg_req(bp, &req, num_vfs);
+
+ bp->pf.active_vfs = 0;
+ for (i = 0; i < num_vfs; i++) {
+ add_random_mac_if_needed(bp, &req, i);
+
+ HWRM_PREP(req, FUNC_CFG);
+ req.flags = rte_cpu_to_le_32(bp->pf.vf_info[i].func_cfg_flags);
+ req.fid = rte_cpu_to_le_16(bp->pf.vf_info[i].fid);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ /* Clear enable flag for next pass */
+ req.enables &= ~rte_cpu_to_le_32(
+ HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+
+ if (rc || resp->error_code) {
+ PMD_DRV_LOG(ERR,
+ "Failed to initizlie VF %d\n", i);
+ PMD_DRV_LOG(ERR,
+ "Not all VFs available. (%d, %d)\n",
+ rc, resp->error_code);
+ HWRM_UNLOCK();
+ break;
+ }
+
+ HWRM_UNLOCK();
+
+ reserve_resources_from_vf(bp, &req, i);
+ bp->pf.active_vfs++;
+ bnxt_hwrm_func_clr_stats(bp, bp->pf.vf_info[i].fid);
+ }
+
+ /*
+ * Now configure the PF to use "the rest" of the resources
+ * We're using STD_TX_RING_MODE here though which will limit the TX
+ * rings. This will allow QoS to function properly. Not setting this
+ * will cause PF rings to break bandwidth settings.
+ */
+ rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings);
+ if (rc)
+ goto error_free;
+
+ rc = update_pf_resource_max(bp);
+ if (rc)
+ goto error_free;
+
+ return rc;
+
+error_free:
+ bnxt_hwrm_func_buf_unrgtr(bp);
+ return rc;
+}
+
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp)
+{
+ struct hwrm_func_cfg_input req = {0};
+ struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc;
+
+ HWRM_PREP(req, FUNC_CFG);
+
+ req.fid = rte_cpu_to_le_16(0xffff);
+ req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE);
+ req.evb_mode = bp->pf.evb_mode;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
+ uint8_t tunnel_type)
+{
+ struct hwrm_tunnel_dst_port_alloc_input req = {0};
+ struct hwrm_tunnel_dst_port_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc = 0;
+
+ HWRM_PREP(req, TUNNEL_DST_PORT_ALLOC);
+ req.tunnel_type = tunnel_type;
+ req.tunnel_dst_port_val = port;
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+ HWRM_CHECK_RESULT();
+
+ switch (tunnel_type) {
+ case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN:
+ bp->vxlan_fw_dst_port_id = resp->tunnel_dst_port_id;
+ bp->vxlan_port = port;
+ break;
+ case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE:
+ bp->geneve_fw_dst_port_id = resp->tunnel_dst_port_id;
+ bp->geneve_port = port;
+ break;
+ default:
+ break;
+ }
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
+ uint8_t tunnel_type)
+{
+ struct hwrm_tunnel_dst_port_free_input req = {0};
+ struct hwrm_tunnel_dst_port_free_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc = 0;
+
+ HWRM_PREP(req, TUNNEL_DST_PORT_FREE);
+
+ req.tunnel_type = tunnel_type;
+ req.tunnel_dst_port_id = rte_cpu_to_be_16(port);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf,
+ uint32_t flags)
+{
+ struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_func_cfg_input req = {0};
+ int rc;
+
+ HWRM_PREP(req, FUNC_CFG);
+
+ req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+ req.flags = rte_cpu_to_le_32(flags);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp)
+{
+ uint32_t *flag = flagp;
+
+ vnic->flags = *flag;
+}
+
+int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+}
+
+int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
+{
+ int rc = 0;
+ struct hwrm_func_buf_rgtr_input req = {.req_type = 0 };
+ struct hwrm_func_buf_rgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_BUF_RGTR);
+
+ req.req_buf_num_pages = rte_cpu_to_le_16(1);
+ req.req_buf_page_size = rte_cpu_to_le_16(
+ page_getenum(bp->pf.active_vfs * HWRM_MAX_REQ_LEN));
+ req.req_buf_len = rte_cpu_to_le_16(HWRM_MAX_REQ_LEN);
+ req.req_buf_page_addr0 =
+ rte_cpu_to_le_64(rte_mem_virt2iova(bp->pf.vf_req_buf));
+ if (req.req_buf_page_addr0 == 0) {
+ PMD_DRV_LOG(ERR,
+ "unable to map buffer address to physical memory\n");
+ return -ENOMEM;
+ }
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp)
+{
+ int rc = 0;
+ struct hwrm_func_buf_unrgtr_input req = {.req_type = 0 };
+ struct hwrm_func_buf_unrgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_BUF_UNRGTR);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp)
+{
+ struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_func_cfg_input req = {0};
+ int rc;
+
+ HWRM_PREP(req, FUNC_CFG);
+
+ req.fid = rte_cpu_to_le_16(0xffff);
+ req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
+ req.enables = rte_cpu_to_le_32(
+ HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+ req.async_event_cr = rte_cpu_to_le_16(
+ bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp)
+{
+ struct hwrm_func_vf_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_func_vf_cfg_input req = {0};
+ int rc;
+
+ HWRM_PREP(req, FUNC_VF_CFG);
+
+ req.enables = rte_cpu_to_le_32(
+ HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+ req.async_event_cr = rte_cpu_to_le_16(
+ bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf)
+{
+ struct hwrm_func_cfg_input req = {0};
+ struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ uint16_t dflt_vlan, fid;
+ uint32_t func_cfg_flags;
+ int rc = 0;
+
+ HWRM_PREP(req, FUNC_CFG);
+
+ if (is_vf) {
+ dflt_vlan = bp->pf.vf_info[vf].dflt_vlan;
+ fid = bp->pf.vf_info[vf].fid;
+ func_cfg_flags = bp->pf.vf_info[vf].func_cfg_flags;
+ } else {
+ fid = rte_cpu_to_le_16(0xffff);
+ func_cfg_flags = bp->pf.func_cfg_flags;
+ dflt_vlan = bp->vlan;
+ }
+
+ req.flags = rte_cpu_to_le_32(func_cfg_flags);
+ req.fid = rte_cpu_to_le_16(fid);
+ req.enables |= rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN);
+ req.dflt_vlan = rte_cpu_to_le_16(dflt_vlan);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
+ uint16_t max_bw, uint16_t enables)
+{
+ struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_func_cfg_input req = {0};
+ int rc;
+
+ HWRM_PREP(req, FUNC_CFG);
+
+ req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+ req.enables |= rte_cpu_to_le_32(enables);
+ req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+ req.max_bw = rte_cpu_to_le_32(max_bw);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf)
+{
+ struct hwrm_func_cfg_input req = {0};
+ struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc = 0;
+
+ HWRM_PREP(req, FUNC_CFG);
+
+ req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+ req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+ req.enables |= rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN);
+ req.dflt_vlan = rte_cpu_to_le_16(bp->pf.vf_info[vf].dflt_vlan);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_set_async_event_cr(struct bnxt *bp)
+{
+ int rc;
+
+ if (BNXT_PF(bp))
+ rc = bnxt_hwrm_func_cfg_def_cp(bp);
+ else
+ rc = bnxt_hwrm_vf_func_cfg_def_cp(bp);
+
+ return rc;
+}
+
+int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
+ void *encaped, size_t ec_size)
+{
+ int rc = 0;
+ struct hwrm_reject_fwd_resp_input req = {.req_type = 0};
+ struct hwrm_reject_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (ec_size > sizeof(req.encap_request))
+ return -1;
+
+ HWRM_PREP(req, REJECT_FWD_RESP);
+
+ req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
+ memcpy(req.encap_request, encaped, ec_size);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
+ struct ether_addr *mac)
+{
+ struct hwrm_func_qcfg_input req = {0};
+ struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+ int rc;
+
+ HWRM_PREP(req, FUNC_QCFG);
+
+ req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ memcpy(mac->addr_bytes, resp->mac_address, ETHER_ADDR_LEN);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
+ void *encaped, size_t ec_size)
+{
+ int rc = 0;
+ struct hwrm_exec_fwd_resp_input req = {.req_type = 0};
+ struct hwrm_exec_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (ec_size > sizeof(req.encap_request))
+ return -1;
+
+ HWRM_PREP(req, EXEC_FWD_RESP);
+
+ req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
+ memcpy(req.encap_request, encaped, ec_size);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx,
+ struct rte_eth_stats *stats, uint8_t rx)
+{
+ int rc = 0;
+ struct hwrm_stat_ctx_query_input req = {.req_type = 0};
+ struct hwrm_stat_ctx_query_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, STAT_CTX_QUERY);
+
+ req.stat_ctx_id = rte_cpu_to_le_32(cid);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ if (rx) {
+ stats->q_ipackets[idx] = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+ stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_mcast_pkts);
+ stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_bcast_pkts);
+ stats->q_ibytes[idx] = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+ stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_mcast_bytes);
+ stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_bcast_bytes);
+ stats->q_errors[idx] = rte_le_to_cpu_64(resp->rx_err_pkts);
+ stats->q_errors[idx] += rte_le_to_cpu_64(resp->rx_drop_pkts);
+ } else {
+ stats->q_opackets[idx] = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+ stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_mcast_pkts);
+ stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_bcast_pkts);
+ stats->q_obytes[idx] = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+ stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_mcast_bytes);
+ stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_bcast_bytes);
+ stats->q_errors[idx] += rte_le_to_cpu_64(resp->tx_err_pkts);
+ }
+
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_port_qstats(struct bnxt *bp)
+{
+ struct hwrm_port_qstats_input req = {0};
+ struct hwrm_port_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+ struct bnxt_pf_info *pf = &bp->pf;
+ int rc;
+
+ HWRM_PREP(req, PORT_QSTATS);
+
+ req.port_id = rte_cpu_to_le_16(pf->port_id);
+ req.tx_stat_host_addr = rte_cpu_to_le_64(bp->hw_tx_port_stats_map);
+ req.rx_stat_host_addr = rte_cpu_to_le_64(bp->hw_rx_port_stats_map);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp)
+{
+ struct hwrm_port_clr_stats_input req = {0};
+ struct hwrm_port_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+ struct bnxt_pf_info *pf = &bp->pf;
+ int rc;
+
+ /* Not allowed on NS2 device, NPAR, MultiHost, VF */
+ if (!(bp->flags & BNXT_FLAG_PORT_STATS) || BNXT_VF(bp) ||
+ BNXT_NPAR(bp) || BNXT_MH(bp) || BNXT_TOTAL_VFS(bp))
+ return 0;
+
+ HWRM_PREP(req, PORT_CLR_STATS);
+
+ req.port_id = rte_cpu_to_le_16(pf->port_id);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_port_led_qcaps(struct bnxt *bp)
+{
+ struct hwrm_port_led_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_port_led_qcaps_input req = {0};
+ int rc;
+
+ if (BNXT_VF(bp))
+ return 0;
+
+ HWRM_PREP(req, PORT_LED_QCAPS);
+ req.port_id = bp->pf.port_id;
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ if (resp->num_leds > 0 && resp->num_leds < BNXT_MAX_LED) {
+ unsigned int i;
+
+ bp->num_leds = resp->num_leds;
+ memcpy(bp->leds, &resp->led0_id,
+ sizeof(bp->leds[0]) * bp->num_leds);
+ for (i = 0; i < bp->num_leds; i++) {
+ struct bnxt_led_info *led = &bp->leds[i];
+
+ uint16_t caps = led->led_state_caps;
+
+ if (!led->led_group_id ||
+ !BNXT_LED_ALT_BLINK_CAP(caps)) {
+ bp->num_leds = 0;
+ break;
+ }
+ }
+ }
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on)
+{
+ struct hwrm_port_led_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_port_led_cfg_input req = {0};
+ struct bnxt_led_cfg *led_cfg;
+ uint8_t led_state = HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_DEFAULT;
+ uint16_t duration = 0;
+ int rc, i;
+
+ if (!bp->num_leds || BNXT_VF(bp))
+ return -EOPNOTSUPP;
+
+ HWRM_PREP(req, PORT_LED_CFG);
+
+ if (led_on) {
+ led_state = HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINKALT;
+ duration = rte_cpu_to_le_16(500);
+ }
+ req.port_id = bp->pf.port_id;
+ req.num_leds = bp->num_leds;
+ led_cfg = (struct bnxt_led_cfg *)&req.led0_id;
+ for (i = 0; i < bp->num_leds; i++, led_cfg++) {
+ req.enables |= BNXT_LED_DFLT_ENABLES(i);
+ led_cfg->led_id = bp->leds[i].led_id;
+ led_cfg->led_state = led_state;
+ led_cfg->led_blink_on = duration;
+ led_cfg->led_blink_off = duration;
+ led_cfg->led_group_id = bp->leds[i].led_group_id;
+ }
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_nvm_get_dir_info(struct bnxt *bp, uint32_t *entries,
+ uint32_t *length)
+{
+ int rc;
+ struct hwrm_nvm_get_dir_info_input req = {0};
+ struct hwrm_nvm_get_dir_info_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, NVM_GET_DIR_INFO);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ if (!rc) {
+ *entries = rte_le_to_cpu_32(resp->entries);
+ *length = rte_le_to_cpu_32(resp->entry_length);
+ }
+ return rc;
+}
+
+int bnxt_get_nvram_directory(struct bnxt *bp, uint32_t len, uint8_t *data)
+{
+ int rc;
+ uint32_t dir_entries;
+ uint32_t entry_length;
+ uint8_t *buf;
+ size_t buflen;
+ rte_iova_t dma_handle;
+ struct hwrm_nvm_get_dir_entries_input req = {0};
+ struct hwrm_nvm_get_dir_entries_output *resp = bp->hwrm_cmd_resp_addr;
+
+ rc = bnxt_hwrm_nvm_get_dir_info(bp, &dir_entries, &entry_length);
+ if (rc != 0)
+ return rc;
+
+ *data++ = dir_entries;
+ *data++ = entry_length;
+ len -= 2;
+ memset(data, 0xff, len);
+
+ buflen = dir_entries * entry_length;
+ buf = rte_malloc("nvm_dir", buflen, 0);
+ rte_mem_lock_page(buf);
+ if (buf == NULL)
+ return -ENOMEM;
+ dma_handle = rte_mem_virt2iova(buf);
+ if (dma_handle == 0) {
+ PMD_DRV_LOG(ERR,
+ "unable to map response address to physical memory\n");
+ return -ENOMEM;
+ }
+ HWRM_PREP(req, NVM_GET_DIR_ENTRIES);
+ req.host_dest_addr = rte_cpu_to_le_64(dma_handle);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ if (rc == 0)
+ memcpy(data, buf, len > buflen ? buflen : len);
+
+ rte_free(buf);
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_get_nvram_item(struct bnxt *bp, uint32_t index,
+ uint32_t offset, uint32_t length,
+ uint8_t *data)
+{
+ int rc;
+ uint8_t *buf;
+ rte_iova_t dma_handle;
+ struct hwrm_nvm_read_input req = {0};
+ struct hwrm_nvm_read_output *resp = bp->hwrm_cmd_resp_addr;
+
+ buf = rte_malloc("nvm_item", length, 0);
+ rte_mem_lock_page(buf);
+ if (!buf)
+ return -ENOMEM;
+
+ dma_handle = rte_mem_virt2iova(buf);
+ if (dma_handle == 0) {
+ PMD_DRV_LOG(ERR,
+ "unable to map response address to physical memory\n");
+ return -ENOMEM;
+ }
+ HWRM_PREP(req, NVM_READ);
+ req.host_dest_addr = rte_cpu_to_le_64(dma_handle);
+ req.dir_idx = rte_cpu_to_le_16(index);
+ req.offset = rte_cpu_to_le_32(offset);
+ req.len = rte_cpu_to_le_32(length);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+ if (rc == 0)
+ memcpy(data, buf, length);
+
+ rte_free(buf);
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_erase_nvram_directory(struct bnxt *bp, uint8_t index)
+{
+ int rc;
+ struct hwrm_nvm_erase_dir_entry_input req = {0};
+ struct hwrm_nvm_erase_dir_entry_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, NVM_ERASE_DIR_ENTRY);
+ req.dir_idx = rte_cpu_to_le_16(index);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+
+int bnxt_hwrm_flash_nvram(struct bnxt *bp, uint16_t dir_type,
+ uint16_t dir_ordinal, uint16_t dir_ext,
+ uint16_t dir_attr, const uint8_t *data,
+ size_t data_len)
+{
+ int rc;
+ struct hwrm_nvm_write_input req = {0};
+ struct hwrm_nvm_write_output *resp = bp->hwrm_cmd_resp_addr;
+ rte_iova_t dma_handle;
+ uint8_t *buf;
+
+ buf = rte_malloc("nvm_write", data_len, 0);
+ rte_mem_lock_page(buf);
+ if (!buf)
+ return -ENOMEM;
+
+ dma_handle = rte_mem_virt2iova(buf);
+ if (dma_handle == 0) {
+ PMD_DRV_LOG(ERR,
+ "unable to map response address to physical memory\n");
+ return -ENOMEM;
+ }
+ memcpy(buf, data, data_len);
+
+ HWRM_PREP(req, NVM_WRITE);
+
+ req.dir_type = rte_cpu_to_le_16(dir_type);
+ req.dir_ordinal = rte_cpu_to_le_16(dir_ordinal);
+ req.dir_ext = rte_cpu_to_le_16(dir_ext);
+ req.dir_attr = rte_cpu_to_le_16(dir_attr);
+ req.dir_data_length = rte_cpu_to_le_32(data_len);
+ req.host_src_addr = rte_cpu_to_le_64(dma_handle);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ rte_free(buf);
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+static void
+bnxt_vnic_count(struct bnxt_vnic_info *vnic __rte_unused, void *cbdata)
+{
+ uint32_t *count = cbdata;
+
+ *count = *count + 1;
+}
+
+static int bnxt_vnic_count_hwrm_stub(struct bnxt *bp __rte_unused,
+ struct bnxt_vnic_info *vnic __rte_unused)
+{
+ return 0;
+}
+
+int bnxt_vf_vnic_count(struct bnxt *bp, uint16_t vf)
+{
+ uint32_t count = 0;
+
+ bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf, bnxt_vnic_count,
+ &count, bnxt_vnic_count_hwrm_stub);
+
+ return count;
+}
+
+static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf,
+ uint16_t *vnic_ids)
+{
+ struct hwrm_func_vf_vnic_ids_query_input req = {0};
+ struct hwrm_func_vf_vnic_ids_query_output *resp =
+ bp->hwrm_cmd_resp_addr;
+ int rc;
+
+ /* First query all VNIC ids */
+ HWRM_PREP(req, FUNC_VF_VNIC_IDS_QUERY);
+
+ req.vf_id = rte_cpu_to_le_16(bp->pf.first_vf_id + vf);
+ req.max_vnic_id_cnt = rte_cpu_to_le_32(bp->pf.total_vnics);
+ req.vnic_id_tbl_addr = rte_cpu_to_le_64(rte_mem_virt2iova(vnic_ids));
+
+ if (req.vnic_id_tbl_addr == 0) {
+ HWRM_UNLOCK();
+ PMD_DRV_LOG(ERR,
+ "unable to map VNIC ID table address to physical memory\n");
+ return -ENOMEM;
+ }
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+ if (rc) {
+ HWRM_UNLOCK();
+ PMD_DRV_LOG(ERR, "hwrm_func_vf_vnic_query failed rc:%d\n", rc);
+ return -1;
+ } else if (resp->error_code) {
+ rc = rte_le_to_cpu_16(resp->error_code);
+ HWRM_UNLOCK();
+ PMD_DRV_LOG(ERR, "hwrm_func_vf_vnic_query error %d\n", rc);
+ return -1;
+ }
+ rc = rte_le_to_cpu_32(resp->vnic_id_cnt);
+
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+/*
+ * This function queries the VNIC IDs for a specified VF. It then calls
+ * the vnic_cb to update the necessary field in vnic_info with cbdata.
+ * Then it calls the hwrm_cb function to program this new vnic configuration.
+ */
+int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
+ void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
+ int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic))
+{
+ struct bnxt_vnic_info vnic;
+ int rc = 0;
+ int i, num_vnic_ids;
+ uint16_t *vnic_ids;
+ size_t vnic_id_sz;
+ size_t sz;
+
+ /* First query all VNIC ids */
+ vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
+ vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
+ RTE_CACHE_LINE_SIZE);
+ if (vnic_ids == NULL) {
+ rc = -ENOMEM;
+ return rc;
+ }
+ for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
+ rte_mem_lock_page(((char *)vnic_ids) + sz);
+
+ num_vnic_ids = bnxt_hwrm_func_vf_vnic_query(bp, vf, vnic_ids);
+
+ if (num_vnic_ids < 0)
+ return num_vnic_ids;
+
+ /* Retrieve VNIC, update bd_stall then update */
+
+ for (i = 0; i < num_vnic_ids; i++) {
+ memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+ vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+ rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf);
+ if (rc)
+ break;
+ if (vnic.mru <= 4) /* Indicates unallocated */
+ continue;
+
+ vnic_cb(&vnic, cbdata);
+
+ rc = hwrm_cb(bp, &vnic);
+ if (rc)
+ break;
+ }
+
+ rte_free(vnic_ids);
+
+ return rc;
+}
+
+int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
+ bool on)
+{
+ struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_func_cfg_input req = {0};
+ int rc;
+
+ HWRM_PREP(req, FUNC_CFG);
+
+ req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+ req.enables |= rte_cpu_to_le_32(
+ HWRM_FUNC_CFG_INPUT_ENABLES_VLAN_ANTISPOOF_MODE);
+ req.vlan_antispoof_mode = on ?
+ HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_VALIDATE_VLAN :
+ HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_NOCHECK;
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf)
+{
+ struct bnxt_vnic_info vnic;
+ uint16_t *vnic_ids;
+ size_t vnic_id_sz;
+ int num_vnic_ids, i;
+ size_t sz;
+ int rc;
+
+ vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
+ vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
+ RTE_CACHE_LINE_SIZE);
+ if (vnic_ids == NULL) {
+ rc = -ENOMEM;
+ return rc;
+ }
+
+ for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
+ rte_mem_lock_page(((char *)vnic_ids) + sz);
+
+ rc = bnxt_hwrm_func_vf_vnic_query(bp, vf, vnic_ids);
+ if (rc <= 0)
+ goto exit;
+ num_vnic_ids = rc;
+
+ /*
+ * Loop through to find the default VNIC ID.
+ * TODO: The easier way would be to obtain the resp->dflt_vnic_id
+ * by sending the hwrm_func_qcfg command to the firmware.
+ */
+ for (i = 0; i < num_vnic_ids; i++) {
+ memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+ vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+ rc = bnxt_hwrm_vnic_qcfg(bp, &vnic,
+ bp->pf.first_vf_id + vf);
+ if (rc)
+ goto exit;
+ if (vnic.func_default) {
+ rte_free(vnic_ids);
+ return vnic.fw_vnic_id;
+ }
+ }
+ /* Could not find a default VNIC. */
+ PMD_DRV_LOG(ERR, "No default VNIC\n");
+exit:
+ rte_free(vnic_ids);
+ return -1;
+}
+
+int bnxt_hwrm_set_em_filter(struct bnxt *bp,
+ uint16_t dst_id,
+ struct bnxt_filter_info *filter)
+{
+ int rc = 0;
+ struct hwrm_cfa_em_flow_alloc_input req = {.req_type = 0 };
+ struct hwrm_cfa_em_flow_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+ uint32_t enables = 0;
+
+ if (filter->fw_em_filter_id != UINT64_MAX)
+ bnxt_hwrm_clear_em_filter(bp, filter);
+
+ HWRM_PREP(req, CFA_EM_FLOW_ALLOC);
+
+ req.flags = rte_cpu_to_le_32(filter->flags);
+
+ enables = filter->enables |
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_ID;
+ req.dst_id = rte_cpu_to_le_16(dst_id);
+
+ if (filter->ip_addr_type) {
+ req.ip_addr_type = filter->ip_addr_type;
+ enables |= HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_IPADDR_TYPE;
+ }
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_L2_FILTER_ID)
+ req.l2_filter_id = rte_cpu_to_le_64(filter->fw_l2_filter_id);
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_SRC_MACADDR)
+ memcpy(req.src_macaddr, filter->src_macaddr,
+ ETHER_ADDR_LEN);
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_MACADDR)
+ memcpy(req.dst_macaddr, filter->dst_macaddr,
+ ETHER_ADDR_LEN);
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_OVLAN_VID)
+ req.ovlan_vid = filter->l2_ovlan;
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_IVLAN_VID)
+ req.ivlan_vid = filter->l2_ivlan;
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_ETHERTYPE)
+ req.ethertype = rte_cpu_to_be_16(filter->ethertype);
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_IP_PROTOCOL)
+ req.ip_protocol = filter->ip_protocol;
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_SRC_IPADDR)
+ req.src_ipaddr[0] = rte_cpu_to_be_32(filter->src_ipaddr[0]);
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_IPADDR)
+ req.dst_ipaddr[0] = rte_cpu_to_be_32(filter->dst_ipaddr[0]);
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_SRC_PORT)
+ req.src_port = rte_cpu_to_be_16(filter->src_port);
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_PORT)
+ req.dst_port = rte_cpu_to_be_16(filter->dst_port);
+ if (enables &
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID)
+ req.mirror_vnic_id = filter->mirror_vnic_id;
+
+ req.enables = rte_cpu_to_le_32(enables);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ filter->fw_em_filter_id = rte_le_to_cpu_64(resp->em_filter_id);
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_clear_em_filter(struct bnxt *bp, struct bnxt_filter_info *filter)
+{
+ int rc = 0;
+ struct hwrm_cfa_em_flow_free_input req = {.req_type = 0 };
+ struct hwrm_cfa_em_flow_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (filter->fw_em_filter_id == UINT64_MAX)
+ return 0;
+
+ PMD_DRV_LOG(ERR, "Clear EM filter\n");
+ HWRM_PREP(req, CFA_EM_FLOW_FREE);
+
+ req.em_filter_id = rte_cpu_to_le_64(filter->fw_em_filter_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ filter->fw_em_filter_id = UINT64_MAX;
+ filter->fw_l2_filter_id = UINT64_MAX;
+
+ return 0;
+}
+
+int bnxt_hwrm_set_ntuple_filter(struct bnxt *bp,
+ uint16_t dst_id,
+ struct bnxt_filter_info *filter)
+{
+ int rc = 0;
+ struct hwrm_cfa_ntuple_filter_alloc_input req = {.req_type = 0 };
+ struct hwrm_cfa_ntuple_filter_alloc_output *resp =
+ bp->hwrm_cmd_resp_addr;
+ uint32_t enables = 0;
+
+ if (filter->fw_ntuple_filter_id != UINT64_MAX)
+ bnxt_hwrm_clear_ntuple_filter(bp, filter);
+
+ HWRM_PREP(req, CFA_NTUPLE_FILTER_ALLOC);
+
+ req.flags = rte_cpu_to_le_32(filter->flags);
+
+ enables = filter->enables |
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_ID;
+ req.dst_id = rte_cpu_to_le_16(dst_id);
+
+
+ if (filter->ip_addr_type) {
+ req.ip_addr_type = filter->ip_addr_type;
+ enables |=
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_IPADDR_TYPE;
+ }
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID)
+ req.l2_filter_id = rte_cpu_to_le_64(filter->fw_l2_filter_id);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_MACADDR)
+ memcpy(req.src_macaddr, filter->src_macaddr,
+ ETHER_ADDR_LEN);
+ //if (enables &
+ //HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_MACADDR)
+ //memcpy(req.dst_macaddr, filter->dst_macaddr,
+ //ETHER_ADDR_LEN);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_ETHERTYPE)
+ req.ethertype = rte_cpu_to_be_16(filter->ethertype);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_IP_PROTOCOL)
+ req.ip_protocol = filter->ip_protocol;
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_IPADDR)
+ req.src_ipaddr[0] = rte_cpu_to_le_32(filter->src_ipaddr[0]);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_IPADDR_MASK)
+ req.src_ipaddr_mask[0] =
+ rte_cpu_to_le_32(filter->src_ipaddr_mask[0]);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_IPADDR)
+ req.dst_ipaddr[0] = rte_cpu_to_le_32(filter->dst_ipaddr[0]);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_IPADDR_MASK)
+ req.dst_ipaddr_mask[0] =
+ rte_cpu_to_be_32(filter->dst_ipaddr_mask[0]);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_PORT)
+ req.src_port = rte_cpu_to_le_16(filter->src_port);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_PORT_MASK)
+ req.src_port_mask = rte_cpu_to_le_16(filter->src_port_mask);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_PORT)
+ req.dst_port = rte_cpu_to_le_16(filter->dst_port);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_PORT_MASK)
+ req.dst_port_mask = rte_cpu_to_le_16(filter->dst_port_mask);
+ if (enables &
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID)
+ req.mirror_vnic_id = filter->mirror_vnic_id;
+
+ req.enables = rte_cpu_to_le_32(enables);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+
+ filter->fw_ntuple_filter_id = rte_le_to_cpu_64(resp->ntuple_filter_id);
+ HWRM_UNLOCK();
+
+ return rc;
+}
+
+int bnxt_hwrm_clear_ntuple_filter(struct bnxt *bp,
+ struct bnxt_filter_info *filter)
+{
+ int rc = 0;
+ struct hwrm_cfa_ntuple_filter_free_input req = {.req_type = 0 };
+ struct hwrm_cfa_ntuple_filter_free_output *resp =
+ bp->hwrm_cmd_resp_addr;
+
+ if (filter->fw_ntuple_filter_id == UINT64_MAX)
+ return 0;
+
+ HWRM_PREP(req, CFA_NTUPLE_FILTER_FREE);
+
+ req.ntuple_filter_id = rte_cpu_to_le_64(filter->fw_ntuple_filter_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+
+ filter->fw_ntuple_filter_id = UINT64_MAX;
+
+ return 0;
+}
+
+int bnxt_vnic_rss_configure(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ unsigned int rss_idx, fw_idx, i;
+
+ if (vnic->rss_table && vnic->hash_type) {
+ /*
+ * Fill the RSS hash & redirection table with
+ * ring group ids for all VNICs
+ */
+ for (rss_idx = 0, fw_idx = 0; rss_idx < HW_HASH_INDEX_SIZE;
+ rss_idx++, fw_idx++) {
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ fw_idx %= bp->rx_cp_nr_rings;
+ if (vnic->fw_grp_ids[fw_idx] !=
+ INVALID_HW_RING_ID)
+ break;
+ fw_idx++;
+ }
+ if (i == bp->rx_cp_nr_rings)
+ return 0;
+ vnic->rss_table[rss_idx] =
+ vnic->fw_grp_ids[fw_idx];
+ }
+ return bnxt_hwrm_vnic_rss_cfg(bp, vnic);
+ }
+ return 0;
+}
+
+static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal,
+ struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req)
+{
+ uint16_t flags;
+
+ req->num_cmpl_aggr_int = rte_cpu_to_le_16(hw_coal->num_cmpl_aggr_int);
+
+ /* This is a 6-bit value and must not be 0, or we'll get non stop IRQ */
+ req->num_cmpl_dma_aggr = rte_cpu_to_le_16(hw_coal->num_cmpl_dma_aggr);
+
+ /* This is a 6-bit value and must not be 0, or we'll get non stop IRQ */
+ req->num_cmpl_dma_aggr_during_int =
+ rte_cpu_to_le_16(hw_coal->num_cmpl_dma_aggr_during_int);
+
+ req->int_lat_tmr_max = rte_cpu_to_le_16(hw_coal->int_lat_tmr_max);
+
+ /* min timer set to 1/2 of interrupt timer */
+ req->int_lat_tmr_min = rte_cpu_to_le_16(hw_coal->int_lat_tmr_min);
+
+ /* buf timer set to 1/4 of interrupt timer */
+ req->cmpl_aggr_dma_tmr = rte_cpu_to_le_16(hw_coal->cmpl_aggr_dma_tmr);
+
+ req->cmpl_aggr_dma_tmr_during_int =
+ rte_cpu_to_le_16(hw_coal->cmpl_aggr_dma_tmr_during_int);
+
+ flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET |
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_RING_IDLE;
+ req->flags = rte_cpu_to_le_16(flags);
+}
+
+int bnxt_hwrm_set_ring_coal(struct bnxt *bp,
+ struct bnxt_coal *coal, uint16_t ring_id)
+{
+ struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req = {0};
+ struct hwrm_ring_cmpl_ring_cfg_aggint_params_output *resp =
+ bp->hwrm_cmd_resp_addr;
+ int rc;
+
+ /* Set ring coalesce parameters only for Stratus 100G NIC */
+ if (!bnxt_stratus_device(bp))
+ return 0;
+
+ HWRM_PREP(req, RING_CMPL_RING_CFG_AGGINT_PARAMS);
+ bnxt_hwrm_set_coal_params(coal, &req);
+ req.ring_id = rte_cpu_to_le_16(ring_id);
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+ HWRM_CHECK_RESULT();
+ HWRM_UNLOCK();
+ return 0;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_hwrm.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_hwrm.h
new file mode 100644
index 00000000..379aac6e
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_hwrm.h
@@ -0,0 +1,177 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_HWRM_H_
+#define _BNXT_HWRM_H_
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+struct bnxt;
+struct bnxt_filter_info;
+struct bnxt_cp_ring_info;
+
+#define HWRM_SEQ_ID_INVALID -1U
+/* Convert Bit field location to value */
+#define ASYNC_CMPL_EVENT_ID_LINK_STATUS_CHANGE \
+ (1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE)
+#define ASYNC_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED \
+ (1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED)
+#define ASYNC_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE \
+ (1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE)
+#define ASYNC_CMPL_EVENT_ID_PF_DRVR_UNLOAD \
+ (1 << (HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD - 32))
+#define ASYNC_CMPL_EVENT_ID_VF_CFG_CHANGE \
+ (1 << (HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE - 32))
+
+#define HWRM_QUEUE_SERVICE_PROFILE_LOSSY \
+ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY
+
+#define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MINIMAL_STATIC \
+ HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MINIMAL_STATIC
+
+int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+ uint16_t vlan_count,
+ struct bnxt_vlan_table_entry *vlan_table);
+int bnxt_hwrm_cfa_vlan_antispoof_cfg(struct bnxt *bp, uint16_t fid,
+ uint16_t vlan_count,
+ struct bnxt_vlan_antispoof_table_entry *vlan_table);
+int bnxt_hwrm_clear_l2_filter(struct bnxt *bp,
+ struct bnxt_filter_info *filter);
+int bnxt_hwrm_set_l2_filter(struct bnxt *bp,
+ uint16_t dst_id,
+ struct bnxt_filter_info *filter);
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
+ void *encaped, size_t ec_size);
+int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
+ void *encaped, size_t ec_size);
+
+int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp);
+int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp);
+int bnxt_hwrm_func_driver_register(struct bnxt *bp);
+int bnxt_hwrm_func_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_reset(struct bnxt *bp);
+int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
+int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
+ struct rte_eth_stats *stats);
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+ uint64_t *dropped);
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid);
+int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp);
+int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
+
+int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
+
+int bnxt_hwrm_set_async_event_cr(struct bnxt *bp);
+int bnxt_hwrm_ring_alloc(struct bnxt *bp,
+ struct bnxt_ring *ring,
+ uint32_t ring_type, uint32_t map_index,
+ uint32_t stats_ctx_id, uint32_t cmpl_ring_id);
+int bnxt_hwrm_ring_free(struct bnxt *bp,
+ struct bnxt_ring *ring, uint32_t ring_type);
+int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned int idx);
+int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned int idx);
+
+int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
+int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
+ struct bnxt_cp_ring_info *cpr, unsigned int idx);
+int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
+ struct bnxt_cp_ring_info *cpr, unsigned int idx);
+int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx,
+ struct rte_eth_stats *stats, uint8_t rx);
+
+int bnxt_hwrm_ver_get(struct bnxt *bp);
+
+int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+ int16_t fw_vf_id);
+int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic, bool enable);
+
+int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
+int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
+int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp);
+int bnxt_free_all_hwrm_rings(struct bnxt *bp);
+int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp);
+int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp);
+int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_clear_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+void bnxt_free_all_hwrm_resources(struct bnxt *bp);
+void bnxt_free_hwrm_resources(struct bnxt *bp);
+void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index);
+int bnxt_alloc_hwrm_resources(struct bnxt *bp);
+int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link);
+int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up);
+int bnxt_hwrm_func_qcfg(struct bnxt *bp);
+int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_reserve_vf_resc(struct bnxt *bp, bool test);
+int bnxt_hwrm_allocate_pf_only(struct bnxt *bp);
+int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
+int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
+ const uint8_t *mac_addr);
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
+int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
+ uint16_t max_bw, uint16_t enables);
+int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf);
+int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
+ struct ether_addr *mac);
+int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf);
+int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
+ uint8_t tunnel_type);
+int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
+ uint8_t tunnel_type);
+void bnxt_free_tunnel_ports(struct bnxt *bp);
+int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf);
+int bnxt_hwrm_port_qstats(struct bnxt *bp);
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
+int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
+int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf,
+ uint32_t flags);
+void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp);
+int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_vf_vnic_count(struct bnxt *bp, uint16_t vf);
+int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
+ void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
+ int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
+int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
+ bool on);
+int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf);
+int bnxt_hwrm_set_em_filter(struct bnxt *bp, uint16_t dst_id,
+ struct bnxt_filter_info *filter);
+int bnxt_hwrm_clear_em_filter(struct bnxt *bp, struct bnxt_filter_info *filter);
+
+int bnxt_hwrm_set_ntuple_filter(struct bnxt *bp, uint16_t dst_id,
+ struct bnxt_filter_info *filter);
+int bnxt_hwrm_clear_ntuple_filter(struct bnxt *bp,
+ struct bnxt_filter_info *filter);
+int bnxt_get_nvram_directory(struct bnxt *bp, uint32_t len, uint8_t *data);
+int bnxt_hwrm_nvm_get_dir_info(struct bnxt *bp, uint32_t *entries,
+ uint32_t *length);
+int bnxt_hwrm_get_nvram_item(struct bnxt *bp, uint32_t index,
+ uint32_t offset, uint32_t length,
+ uint8_t *data);
+int bnxt_hwrm_erase_nvram_directory(struct bnxt *bp, uint8_t index);
+int bnxt_hwrm_flash_nvram(struct bnxt *bp, uint16_t dir_type,
+ uint16_t dir_ordinal, uint16_t dir_ext,
+ uint16_t dir_attr, const uint8_t *data,
+ size_t data_len);
+int bnxt_hwrm_ptp_cfg(struct bnxt *bp);
+int bnxt_vnic_rss_configure(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_set_ring_coal(struct bnxt *bp,
+ struct bnxt_coal *coal, uint16_t ring_id);
+int bnxt_hwrm_check_vf_rings(struct bnxt *bp);
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_irq.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_irq.c
new file mode 100644
index 00000000..7ef7023e
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_irq.c
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_irq.h"
+#include "bnxt_ring.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * Interrupts
+ */
+
+static void bnxt_int_handler(void *param)
+{
+ struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+ struct cmpl_base *cmp;
+ uint32_t raw_cons;
+ uint32_t cons;
+
+ if (cpr == NULL)
+ return;
+
+ raw_cons = cpr->cp_raw_cons;
+ while (1) {
+ if (!cpr || !cpr->cp_ring_struct)
+ return;
+
+ cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
+ cmp = &cpr->cp_desc_ring[cons];
+
+ if (!CMP_VALID(cmp, raw_cons, cpr->cp_ring_struct))
+ break;
+
+ bnxt_event_hwrm_resp_handler(bp, cmp);
+ raw_cons = NEXT_RAW_CMP(raw_cons);
+ };
+
+ cpr->cp_raw_cons = raw_cons;
+ B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
+}
+
+void bnxt_free_int(struct bnxt *bp)
+{
+ struct bnxt_irq *irq;
+
+ irq = bp->irq_tbl;
+ if (irq) {
+ if (irq->requested) {
+ rte_intr_disable(&bp->pdev->intr_handle);
+ rte_intr_callback_unregister(&bp->pdev->intr_handle,
+ irq->handler,
+ (void *)bp->eth_dev);
+ irq->requested = 0;
+ }
+ rte_free((void *)bp->irq_tbl);
+ bp->irq_tbl = NULL;
+ }
+}
+
+void bnxt_disable_int(struct bnxt *bp)
+{
+ struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+
+ /* Only the default completion ring */
+ if (cpr != NULL && cpr->cp_doorbell != NULL)
+ B_CP_DB_DISARM(cpr);
+}
+
+void bnxt_enable_int(struct bnxt *bp)
+{
+ struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+
+ /* Only the default completion ring */
+ if (cpr != NULL && cpr->cp_doorbell != NULL)
+ B_CP_DB_ARM(cpr);
+}
+
+int bnxt_setup_int(struct bnxt *bp)
+{
+ uint16_t total_vecs;
+ const int len = sizeof(bp->irq_tbl[0].name);
+ int i, rc = 0;
+
+ /* DPDK host only supports 1 MSI-X vector */
+ total_vecs = 1;
+ bp->irq_tbl = rte_calloc("bnxt_irq_tbl", total_vecs,
+ sizeof(struct bnxt_irq), 0);
+ if (bp->irq_tbl) {
+ for (i = 0; i < total_vecs; i++) {
+ bp->irq_tbl[i].vector = i;
+ snprintf(bp->irq_tbl[i].name, len,
+ "%s-%d", bp->eth_dev->device->name, i);
+ bp->irq_tbl[i].handler = bnxt_int_handler;
+ }
+ } else {
+ rc = -ENOMEM;
+ goto setup_exit;
+ }
+ return 0;
+
+setup_exit:
+ PMD_DRV_LOG(ERR, "bnxt_irq_tbl setup failed\n");
+ return rc;
+}
+
+int bnxt_request_int(struct bnxt *bp)
+{
+ int rc = 0;
+
+ struct bnxt_irq *irq = bp->irq_tbl;
+
+ rte_intr_callback_register(&bp->pdev->intr_handle, irq->handler,
+ (void *)bp->eth_dev);
+ rte_intr_enable(&bp->pdev->intr_handle);
+
+ irq->requested = 1;
+ return rc;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_irq.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_irq.h
new file mode 100644
index 00000000..75ba2135
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_irq.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_IRQ_H_
+#define _BNXT_IRQ_H_
+
+#define BNXT_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET
+#define BNXT_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET
+
+struct bnxt_irq {
+ rte_intr_callback_fn handler;
+ unsigned int vector;
+ uint8_t requested;
+ char name[RTE_ETH_NAME_MAX_LEN + 2];
+};
+
+struct bnxt;
+void bnxt_free_int(struct bnxt *bp);
+void bnxt_disable_int(struct bnxt *bp);
+void bnxt_enable_int(struct bnxt *bp);
+int bnxt_setup_int(struct bnxt *bp);
+int bnxt_request_int(struct bnxt *bp);
+
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_nvm_defs.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_nvm_defs.h
new file mode 100644
index 00000000..ea9d4a9d
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_nvm_defs.h
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_NVM_DEFS_H_
+#define _BNXT_NVM_DEFS_H_
+
+enum bnxt_nvm_directory_type {
+ BNX_DIR_TYPE_UNUSED = 0,
+ BNX_DIR_TYPE_PKG_LOG = 1,
+ BNX_DIR_TYPE_UPDATE = 2,
+ BNX_DIR_TYPE_CHIMP_PATCH = 3,
+ BNX_DIR_TYPE_BOOTCODE = 4,
+ BNX_DIR_TYPE_VPD = 5,
+ BNX_DIR_TYPE_EXP_ROM_MBA = 6,
+ BNX_DIR_TYPE_AVS = 7,
+ BNX_DIR_TYPE_PCIE = 8,
+ BNX_DIR_TYPE_PORT_MACRO = 9,
+ BNX_DIR_TYPE_APE_FW = 10,
+ BNX_DIR_TYPE_APE_PATCH = 11,
+ BNX_DIR_TYPE_KONG_FW = 12,
+ BNX_DIR_TYPE_KONG_PATCH = 13,
+ BNX_DIR_TYPE_BONO_FW = 14,
+ BNX_DIR_TYPE_BONO_PATCH = 15,
+ BNX_DIR_TYPE_TANG_FW = 16,
+ BNX_DIR_TYPE_TANG_PATCH = 17,
+ BNX_DIR_TYPE_BOOTCODE_2 = 18,
+ BNX_DIR_TYPE_CCM = 19,
+ BNX_DIR_TYPE_PCI_CFG = 20,
+ BNX_DIR_TYPE_TSCF_UCODE = 21,
+ BNX_DIR_TYPE_ISCSI_BOOT = 22,
+ BNX_DIR_TYPE_ISCSI_BOOT_IPV6 = 24,
+ BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6 = 25,
+ BNX_DIR_TYPE_ISCSI_BOOT_CFG6 = 26,
+ BNX_DIR_TYPE_EXT_PHY = 27,
+ BNX_DIR_TYPE_SHARED_CFG = 40,
+ BNX_DIR_TYPE_PORT_CFG = 41,
+ BNX_DIR_TYPE_FUNC_CFG = 42,
+ BNX_DIR_TYPE_MGMT_CFG = 48,
+ BNX_DIR_TYPE_MGMT_DATA = 49,
+ BNX_DIR_TYPE_MGMT_WEB_DATA = 50,
+ BNX_DIR_TYPE_MGMT_WEB_META = 51,
+ BNX_DIR_TYPE_MGMT_EVENT_LOG = 52,
+ BNX_DIR_TYPE_MGMT_AUDIT_LOG = 53
+};
+
+#define BNX_DIR_ORDINAL_FIRST 0
+
+#define BNX_DIR_EXT_NONE 0
+#define BNX_DIR_EXT_INACTIVE (1 << 0)
+#define BNX_DIR_EXT_UPDATE (1 << 1)
+
+#define BNX_DIR_ATTR_NONE 0
+#define BNX_DIR_ATTR_NO_CHKSUM (1 << 0)
+#define BNX_DIR_ATTR_PROP_STREAM (1 << 1)
+
+#define BNX_PKG_LOG_MAX_LENGTH 4096
+
+enum bnxnvm_pkglog_field_index {
+ BNX_PKG_LOG_FIELD_IDX_INSTALLED_TIMESTAMP = 0,
+ BNX_PKG_LOG_FIELD_IDX_PKG_DESCRIPTION = 1,
+ BNX_PKG_LOG_FIELD_IDX_PKG_VERSION = 2,
+ BNX_PKG_LOG_FIELD_IDX_PKG_TIMESTAMP = 3,
+ BNX_PKG_LOG_FIELD_IDX_PKG_CHECKSUM = 4,
+ BNX_PKG_LOG_FIELD_IDX_INSTALLED_ITEMS = 5,
+ BNX_PKG_LOG_FIELD_IDX_INSTALLED_MASK = 6
+};
+
+#endif /* Don't add anything after this line */
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_ring.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_ring.c
new file mode 100644
index 00000000..fcbd6bc6
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_ring.c
@@ -0,0 +1,501 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <rte_bitmap.h>
+#include <rte_memzone.h>
+#include <unistd.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_ring.h"
+#include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
+#include "bnxt_txq.h"
+#include "bnxt_txr.h"
+
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * Generic ring handling
+ */
+
+void bnxt_free_ring(struct bnxt_ring *ring)
+{
+ if (!ring)
+ return;
+
+ if (ring->vmem_size && *ring->vmem) {
+ memset((char *)*ring->vmem, 0, ring->vmem_size);
+ *ring->vmem = NULL;
+ }
+ ring->mem_zone = NULL;
+}
+
+/*
+ * Ring groups
+ */
+
+int bnxt_init_ring_grps(struct bnxt *bp)
+{
+ unsigned int i;
+
+ for (i = 0; i < bp->max_ring_grps; i++)
+ memset(&bp->grp_info[i], (uint8_t)HWRM_NA_SIGNATURE,
+ sizeof(struct bnxt_ring_grp_info));
+
+ return 0;
+}
+
+/*
+ * Allocates a completion ring with vmem and stats optionally also allocating
+ * a TX and/or RX ring. Passing NULL as tx_ring_info and/or rx_ring_info
+ * to not allocate them.
+ *
+ * Order in the allocation is:
+ * stats - Always non-zero length
+ * cp vmem - Always zero-length, supported for the bnxt_ring abstraction
+ * tx vmem - Only non-zero length if tx_ring_info is not NULL
+ * rx vmem - Only non-zero length if rx_ring_info is not NULL
+ * cp bd ring - Always non-zero length
+ * tx bd ring - Only non-zero length if tx_ring_info is not NULL
+ * rx bd ring - Only non-zero length if rx_ring_info is not NULL
+ */
+int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
+ struct bnxt_tx_queue *txq,
+ struct bnxt_rx_queue *rxq,
+ struct bnxt_cp_ring_info *cp_ring_info,
+ const char *suffix)
+{
+ struct bnxt_ring *cp_ring = cp_ring_info->cp_ring_struct;
+ struct bnxt_rx_ring_info *rx_ring_info = rxq ? rxq->rx_ring : NULL;
+ struct bnxt_tx_ring_info *tx_ring_info = txq ? txq->tx_ring : NULL;
+ struct bnxt_ring *tx_ring;
+ struct bnxt_ring *rx_ring;
+ struct rte_pci_device *pdev = bp->pdev;
+ uint64_t rx_offloads = bp->eth_dev->data->dev_conf.rxmode.offloads;
+ const struct rte_memzone *mz = NULL;
+ char mz_name[RTE_MEMZONE_NAMESIZE];
+ rte_iova_t mz_phys_addr;
+ int sz;
+
+ int stats_len = (tx_ring_info || rx_ring_info) ?
+ RTE_CACHE_LINE_ROUNDUP(sizeof(struct hwrm_stat_ctx_query_output) -
+ sizeof (struct hwrm_resp_hdr)) : 0;
+
+ int cp_vmem_start = stats_len;
+ int cp_vmem_len = RTE_CACHE_LINE_ROUNDUP(cp_ring->vmem_size);
+
+ int tx_vmem_start = cp_vmem_start + cp_vmem_len;
+ int tx_vmem_len =
+ tx_ring_info ? RTE_CACHE_LINE_ROUNDUP(tx_ring_info->
+ tx_ring_struct->vmem_size) : 0;
+
+ int rx_vmem_start = tx_vmem_start + tx_vmem_len;
+ int rx_vmem_len = rx_ring_info ?
+ RTE_CACHE_LINE_ROUNDUP(rx_ring_info->
+ rx_ring_struct->vmem_size) : 0;
+ int ag_vmem_start = 0;
+ int ag_vmem_len = 0;
+ int cp_ring_start = 0;
+
+ ag_vmem_start = rx_vmem_start + rx_vmem_len;
+ ag_vmem_len = rx_ring_info ? RTE_CACHE_LINE_ROUNDUP(
+ rx_ring_info->ag_ring_struct->vmem_size) : 0;
+ cp_ring_start = ag_vmem_start + ag_vmem_len;
+
+ int cp_ring_len = RTE_CACHE_LINE_ROUNDUP(cp_ring->ring_size *
+ sizeof(struct cmpl_base));
+
+ int tx_ring_start = cp_ring_start + cp_ring_len;
+ int tx_ring_len = tx_ring_info ?
+ RTE_CACHE_LINE_ROUNDUP(tx_ring_info->tx_ring_struct->ring_size *
+ sizeof(struct tx_bd_long)) : 0;
+
+ int rx_ring_start = tx_ring_start + tx_ring_len;
+ int rx_ring_len = rx_ring_info ?
+ RTE_CACHE_LINE_ROUNDUP(rx_ring_info->rx_ring_struct->ring_size *
+ sizeof(struct rx_prod_pkt_bd)) : 0;
+
+ int ag_ring_start = rx_ring_start + rx_ring_len;
+ int ag_ring_len = rx_ring_len * AGG_RING_SIZE_FACTOR;
+
+ int ag_bitmap_start = ag_ring_start + ag_ring_len;
+ int ag_bitmap_len = rx_ring_info ?
+ RTE_CACHE_LINE_ROUNDUP(rte_bitmap_get_memory_footprint(
+ rx_ring_info->rx_ring_struct->ring_size *
+ AGG_RING_SIZE_FACTOR)) : 0;
+
+ int tpa_info_start = ag_bitmap_start + ag_bitmap_len;
+ int tpa_info_len = rx_ring_info ?
+ RTE_CACHE_LINE_ROUNDUP(BNXT_TPA_MAX *
+ sizeof(struct bnxt_tpa_info)) : 0;
+
+ int total_alloc_len = tpa_info_start;
+ if (rx_offloads & DEV_RX_OFFLOAD_TCP_LRO)
+ total_alloc_len += tpa_info_len;
+
+ snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+ "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
+ pdev->addr.bus, pdev->addr.devid, pdev->addr.function, qidx,
+ suffix);
+ mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+ mz = rte_memzone_lookup(mz_name);
+ if (!mz) {
+ mz = rte_memzone_reserve_aligned(mz_name, total_alloc_len,
+ SOCKET_ID_ANY,
+ RTE_MEMZONE_2MB |
+ RTE_MEMZONE_SIZE_HINT_ONLY |
+ RTE_MEMZONE_IOVA_CONTIG,
+ getpagesize());
+ if (mz == NULL)
+ return -ENOMEM;
+ }
+ memset(mz->addr, 0, mz->len);
+ mz_phys_addr = mz->iova;
+ if ((unsigned long)mz->addr == mz_phys_addr) {
+ PMD_DRV_LOG(WARNING,
+ "Memzone physical address same as virtual.\n");
+ PMD_DRV_LOG(WARNING,
+ "Using rte_mem_virt2iova()\n");
+ for (sz = 0; sz < total_alloc_len; sz += getpagesize())
+ rte_mem_lock_page(((char *)mz->addr) + sz);
+ mz_phys_addr = rte_mem_virt2iova(mz->addr);
+ if (mz_phys_addr == 0) {
+ PMD_DRV_LOG(ERR,
+ "unable to map ring address to physical memory\n");
+ return -ENOMEM;
+ }
+ }
+
+ if (tx_ring_info) {
+ txq->mz = mz;
+ tx_ring = tx_ring_info->tx_ring_struct;
+
+ tx_ring->bd = ((char *)mz->addr + tx_ring_start);
+ tx_ring_info->tx_desc_ring = (struct tx_bd_long *)tx_ring->bd;
+ tx_ring->bd_dma = mz_phys_addr + tx_ring_start;
+ tx_ring_info->tx_desc_mapping = tx_ring->bd_dma;
+ tx_ring->mem_zone = (const void *)mz;
+
+ if (!tx_ring->bd)
+ return -ENOMEM;
+ if (tx_ring->vmem_size) {
+ tx_ring->vmem =
+ (void **)((char *)mz->addr + tx_vmem_start);
+ tx_ring_info->tx_buf_ring =
+ (struct bnxt_sw_tx_bd *)tx_ring->vmem;
+ }
+ }
+
+ if (rx_ring_info) {
+ rxq->mz = mz;
+ rx_ring = rx_ring_info->rx_ring_struct;
+
+ rx_ring->bd = ((char *)mz->addr + rx_ring_start);
+ rx_ring_info->rx_desc_ring =
+ (struct rx_prod_pkt_bd *)rx_ring->bd;
+ rx_ring->bd_dma = mz_phys_addr + rx_ring_start;
+ rx_ring_info->rx_desc_mapping = rx_ring->bd_dma;
+ rx_ring->mem_zone = (const void *)mz;
+
+ if (!rx_ring->bd)
+ return -ENOMEM;
+ if (rx_ring->vmem_size) {
+ rx_ring->vmem =
+ (void **)((char *)mz->addr + rx_vmem_start);
+ rx_ring_info->rx_buf_ring =
+ (struct bnxt_sw_rx_bd *)rx_ring->vmem;
+ }
+
+ rx_ring = rx_ring_info->ag_ring_struct;
+
+ rx_ring->bd = ((char *)mz->addr + ag_ring_start);
+ rx_ring_info->ag_desc_ring =
+ (struct rx_prod_pkt_bd *)rx_ring->bd;
+ rx_ring->bd_dma = mz->iova + ag_ring_start;
+ rx_ring_info->ag_desc_mapping = rx_ring->bd_dma;
+ rx_ring->mem_zone = (const void *)mz;
+
+ if (!rx_ring->bd)
+ return -ENOMEM;
+ if (rx_ring->vmem_size) {
+ rx_ring->vmem =
+ (void **)((char *)mz->addr + ag_vmem_start);
+ rx_ring_info->ag_buf_ring =
+ (struct bnxt_sw_rx_bd *)rx_ring->vmem;
+ }
+
+ rx_ring_info->ag_bitmap =
+ rte_bitmap_init(rx_ring_info->rx_ring_struct->ring_size *
+ AGG_RING_SIZE_FACTOR, (uint8_t *)mz->addr +
+ ag_bitmap_start, ag_bitmap_len);
+
+ /* TPA info */
+ if (rx_offloads & DEV_RX_OFFLOAD_TCP_LRO)
+ rx_ring_info->tpa_info =
+ ((struct bnxt_tpa_info *)((char *)mz->addr +
+ tpa_info_start));
+ }
+
+ cp_ring->bd = ((char *)mz->addr + cp_ring_start);
+ cp_ring->bd_dma = mz_phys_addr + cp_ring_start;
+ cp_ring_info->cp_desc_ring = cp_ring->bd;
+ cp_ring_info->cp_desc_mapping = cp_ring->bd_dma;
+ cp_ring->mem_zone = (const void *)mz;
+
+ if (!cp_ring->bd)
+ return -ENOMEM;
+ if (cp_ring->vmem_size)
+ *cp_ring->vmem = ((char *)mz->addr + stats_len);
+ if (stats_len) {
+ cp_ring_info->hw_stats = mz->addr;
+ cp_ring_info->hw_stats_map = mz_phys_addr;
+ }
+ cp_ring_info->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
+ return 0;
+}
+
+static void bnxt_init_dflt_coal(struct bnxt_coal *coal)
+{
+ /* Tick values in micro seconds.
+ * 1 coal_buf x bufs_per_record = 1 completion record.
+ */
+ coal->num_cmpl_aggr_int = BNXT_NUM_CMPL_AGGR_INT;
+ /* This is a 6-bit value and must not be 0, or we'll get non stop IRQ */
+ coal->num_cmpl_dma_aggr = BNXT_NUM_CMPL_DMA_AGGR;
+ /* This is a 6-bit value and must not be 0, or we'll get non stop IRQ */
+ coal->num_cmpl_dma_aggr_during_int = BNXT_NUM_CMPL_DMA_AGGR_DURING_INT;
+ coal->int_lat_tmr_max = BNXT_INT_LAT_TMR_MAX;
+ /* min timer set to 1/2 of interrupt timer */
+ coal->int_lat_tmr_min = BNXT_INT_LAT_TMR_MIN;
+ /* buf timer set to 1/4 of interrupt timer */
+ coal->cmpl_aggr_dma_tmr = BNXT_CMPL_AGGR_DMA_TMR;
+ coal->cmpl_aggr_dma_tmr_during_int = BNXT_CMPL_AGGR_DMA_TMR_DURING_INT;
+}
+
+int bnxt_alloc_hwrm_rx_ring(struct bnxt *bp, int queue_index)
+{
+ struct rte_pci_device *pci_dev = bp->pdev;
+ struct bnxt_rx_queue *rxq = bp->rx_queues[queue_index];
+ struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+ struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
+ struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+ struct bnxt_ring *ring = rxr->rx_ring_struct;
+ unsigned int map_idx = queue_index + bp->rx_cp_nr_rings;
+ int rc = 0;
+
+ bp->grp_info[queue_index].fw_stats_ctx = cpr->hw_stats_ctx_id;
+
+ /* Rx cmpl */
+ rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+ queue_index, HWRM_NA_SIGNATURE,
+ HWRM_NA_SIGNATURE);
+ if (rc)
+ goto err_out;
+
+ cpr->cp_doorbell = (char *)pci_dev->mem_resource[2].addr +
+ queue_index * BNXT_DB_SIZE;
+ bp->grp_info[queue_index].cp_fw_ring_id = cp_ring->fw_ring_id;
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+
+ if (!queue_index) {
+ /*
+ * In order to save completion resources, use the first
+ * completion ring from PF or VF as the default completion ring
+ * for async event and HWRM forward response handling.
+ */
+ bp->def_cp_ring = cpr;
+ rc = bnxt_hwrm_set_async_event_cr(bp);
+ if (rc)
+ goto err_out;
+ }
+ /* Rx ring */
+ rc = bnxt_hwrm_ring_alloc(bp, ring, HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
+ queue_index, cpr->hw_stats_ctx_id,
+ cp_ring->fw_ring_id);
+ if (rc)
+ goto err_out;
+
+ rxr->rx_prod = 0;
+ rxr->rx_doorbell = (char *)pci_dev->mem_resource[2].addr +
+ queue_index * BNXT_DB_SIZE;
+ bp->grp_info[queue_index].rx_fw_ring_id = ring->fw_ring_id;
+ B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+
+ ring = rxr->ag_ring_struct;
+ /* Agg ring */
+ if (!ring)
+ PMD_DRV_LOG(ERR, "Alloc AGG Ring is NULL!\n");
+
+ rc = bnxt_hwrm_ring_alloc(bp, ring, HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
+ map_idx, HWRM_NA_SIGNATURE,
+ cp_ring->fw_ring_id);
+ if (rc)
+ goto err_out;
+
+ PMD_DRV_LOG(DEBUG, "Alloc AGG Done!\n");
+ rxr->ag_prod = 0;
+ rxr->ag_doorbell = (char *)pci_dev->mem_resource[2].addr +
+ map_idx * BNXT_DB_SIZE;
+ bp->grp_info[queue_index].ag_fw_ring_id = ring->fw_ring_id;
+ B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+
+ rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN +
+ ETHER_CRC_LEN + (2 * VLAN_TAG_SIZE);
+
+ if (bp->eth_dev->data->rx_queue_state[queue_index] ==
+ RTE_ETH_QUEUE_STATE_STARTED) {
+ if (bnxt_init_one_rx_ring(rxq)) {
+ RTE_LOG(ERR, PMD,
+ "bnxt_init_one_rx_ring failed!\n");
+ bnxt_rx_queue_release_op(rxq);
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+ B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+ }
+ rxq->index = queue_index;
+ PMD_DRV_LOG(INFO,
+ "queue %d, rx_deferred_start %d, state %d!\n",
+ queue_index, rxq->rx_deferred_start,
+ bp->eth_dev->data->rx_queue_state[queue_index]);
+
+err_out:
+ return rc;
+}
+/* ring_grp usage:
+ * [0] = default completion ring
+ * [1 -> +rx_cp_nr_rings] = rx_cp, rx rings
+ * [1+rx_cp_nr_rings + 1 -> +tx_cp_nr_rings] = tx_cp, tx rings
+ */
+int bnxt_alloc_hwrm_rings(struct bnxt *bp)
+{
+ struct bnxt_coal coal;
+ unsigned int i;
+ int rc = 0;
+
+ bnxt_init_dflt_coal(&coal);
+
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+ struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+ struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
+ struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+ struct bnxt_ring *ring = rxr->rx_ring_struct;
+ unsigned int map_idx = i + bp->rx_cp_nr_rings;
+
+ bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
+
+ /* Rx cmpl */
+ rc = bnxt_hwrm_ring_alloc
+ (bp,
+ cp_ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+ i,
+ HWRM_NA_SIGNATURE,
+ HWRM_NA_SIGNATURE);
+ if (rc)
+ goto err_out;
+ cpr->cp_doorbell = (char *)bp->doorbell_base + i * 0x80;
+ bp->grp_info[i].cp_fw_ring_id = cp_ring->fw_ring_id;
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+ bnxt_hwrm_set_ring_coal(bp, &coal, cp_ring->fw_ring_id);
+
+ if (!i) {
+ /*
+ * In order to save completion resource, use the first
+ * completion ring from PF or VF as the default
+ * completion ring for async event & HWRM
+ * forward response handling.
+ */
+ bp->def_cp_ring = cpr;
+ rc = bnxt_hwrm_set_async_event_cr(bp);
+ if (rc)
+ goto err_out;
+ }
+
+ /* Rx ring */
+ rc = bnxt_hwrm_ring_alloc(bp,
+ ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
+ i,
+ cpr->hw_stats_ctx_id,
+ cp_ring->fw_ring_id);
+ if (rc)
+ goto err_out;
+ rxr->rx_prod = 0;
+ rxr->rx_doorbell = (char *)bp->doorbell_base + i * 0x80;
+ bp->grp_info[i].rx_fw_ring_id = ring->fw_ring_id;
+ B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+
+ ring = rxr->ag_ring_struct;
+ /* Agg ring */
+ if (ring == NULL) {
+ PMD_DRV_LOG(ERR, "Alloc AGG Ring is NULL!\n");
+ goto err_out;
+ }
+
+ rc = bnxt_hwrm_ring_alloc(bp, ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
+ map_idx, HWRM_NA_SIGNATURE,
+ cp_ring->fw_ring_id);
+ if (rc)
+ goto err_out;
+ PMD_DRV_LOG(DEBUG, "Alloc AGG Done!\n");
+ rxr->ag_prod = 0;
+ rxr->ag_doorbell = (char *)bp->doorbell_base + map_idx * 0x80;
+ bp->grp_info[i].ag_fw_ring_id = ring->fw_ring_id;
+ B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+
+ rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN +
+ ETHER_CRC_LEN + (2 * VLAN_TAG_SIZE);
+ if (bnxt_init_one_rx_ring(rxq)) {
+ PMD_DRV_LOG(ERR, "bnxt_init_one_rx_ring failed!\n");
+ bnxt_rx_queue_release_op(rxq);
+ return -ENOMEM;
+ }
+ B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+ B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+ rxq->index = i;
+ }
+
+ for (i = 0; i < bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+ struct bnxt_cp_ring_info *cpr = txq->cp_ring;
+ struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
+ struct bnxt_tx_ring_info *txr = txq->tx_ring;
+ struct bnxt_ring *ring = txr->tx_ring_struct;
+ unsigned int idx = i + bp->rx_cp_nr_rings;
+
+ /* Tx cmpl */
+ rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+ idx, HWRM_NA_SIGNATURE,
+ HWRM_NA_SIGNATURE);
+ if (rc)
+ goto err_out;
+
+ cpr->cp_doorbell = (char *)bp->doorbell_base + idx * 0x80;
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+
+ /* Tx ring */
+ rc = bnxt_hwrm_ring_alloc(bp, ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_TX,
+ idx, cpr->hw_stats_ctx_id,
+ cp_ring->fw_ring_id);
+ if (rc)
+ goto err_out;
+
+ txr->tx_doorbell = (char *)bp->doorbell_base + idx * 0x80;
+ txq->index = idx;
+ bnxt_hwrm_set_ring_coal(bp, &coal, cp_ring->fw_ring_id);
+ }
+
+err_out:
+ return rc;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_ring.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_ring.h
new file mode 100644
index 00000000..1446d784
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_ring.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_RING_H_
+#define _BNXT_RING_H_
+
+#include <inttypes.h>
+
+#include <rte_memory.h>
+
+#define RING_NEXT(ring, idx) (((idx) + 1) & (ring)->ring_mask)
+
+#define DB_IDX_MASK 0xffffff
+#define DB_IDX_VALID (0x1 << 26)
+#define DB_IRQ_DIS (0x1 << 27)
+#define DB_KEY_TX (0x0 << 28)
+#define DB_KEY_RX (0x1 << 28)
+#define DB_KEY_CP (0x2 << 28)
+#define DB_KEY_ST (0x3 << 28)
+#define DB_KEY_TX_PUSH (0x4 << 28)
+#define DB_LONG_TX_PUSH (0x2 << 24)
+
+#define DEFAULT_CP_RING_SIZE 256
+#define DEFAULT_RX_RING_SIZE 256
+#define DEFAULT_TX_RING_SIZE 256
+
+#define BNXT_TPA_MAX 64
+#define AGG_RING_SIZE_FACTOR 2
+#define AGG_RING_MULTIPLIER 2
+
+/* These assume 4k pages */
+#define MAX_RX_DESC_CNT (8 * 1024)
+#define MAX_TX_DESC_CNT (4 * 1024)
+#define MAX_CP_DESC_CNT (16 * 1024)
+
+#define INVALID_HW_RING_ID ((uint16_t)-1)
+#define INVALID_STATS_CTX_ID ((uint16_t)-1)
+
+struct bnxt_ring {
+ void *bd;
+ rte_iova_t bd_dma;
+ uint32_t ring_size;
+ uint32_t ring_mask;
+
+ int vmem_size;
+ void **vmem;
+
+ uint16_t fw_ring_id; /* Ring id filled by Chimp FW */
+ const void *mem_zone;
+};
+
+struct bnxt_ring_grp_info {
+ uint16_t fw_stats_ctx;
+ uint16_t fw_grp_id;
+ uint16_t rx_fw_ring_id;
+ uint16_t cp_fw_ring_id;
+ uint16_t ag_fw_ring_id;
+};
+
+struct bnxt;
+struct bnxt_tx_ring_info;
+struct bnxt_rx_ring_info;
+struct bnxt_cp_ring_info;
+void bnxt_free_ring(struct bnxt_ring *ring);
+int bnxt_init_ring_grps(struct bnxt *bp);
+int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
+ struct bnxt_tx_queue *txq,
+ struct bnxt_rx_queue *rxq,
+ struct bnxt_cp_ring_info *cp_ring_info,
+ const char *suffix);
+int bnxt_alloc_hwrm_rx_ring(struct bnxt *bp, int queue_index);
+int bnxt_alloc_hwrm_rings(struct bnxt *bp);
+
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxq.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxq.c
new file mode 100644
index 00000000..832fc9ec
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxq.c
@@ -0,0 +1,471 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_ring.h"
+#include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
+#include "bnxt_vnic.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * RX Queues
+ */
+
+void bnxt_free_rxq_stats(struct bnxt_rx_queue *rxq)
+{
+ if (rxq && rxq->cp_ring && rxq->cp_ring->hw_stats)
+ rxq->cp_ring->hw_stats = NULL;
+}
+
+int bnxt_mq_rx_configure(struct bnxt *bp)
+{
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ const struct rte_eth_vmdq_rx_conf *conf =
+ &dev_conf->rx_adv_conf.vmdq_rx_conf;
+ unsigned int i, j, nb_q_per_grp = 1, ring_idx = 0;
+ int start_grp_id, end_grp_id = 1, rc = 0;
+ struct bnxt_vnic_info *vnic;
+ struct bnxt_filter_info *filter;
+ enum rte_eth_nb_pools pools = bp->rx_cp_nr_rings, max_pools = 0;
+ struct bnxt_rx_queue *rxq;
+
+ bp->nr_vnics = 0;
+
+ /* Single queue mode */
+ if (bp->rx_cp_nr_rings < 2) {
+ vnic = bnxt_alloc_vnic(bp);
+ if (!vnic) {
+ PMD_DRV_LOG(ERR, "VNIC alloc failed\n");
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ vnic->flags |= BNXT_VNIC_INFO_BCAST;
+ STAILQ_INSERT_TAIL(&bp->ff_pool[0], vnic, next);
+ bp->nr_vnics++;
+
+ rxq = bp->eth_dev->data->rx_queues[0];
+ rxq->vnic = vnic;
+
+ vnic->func_default = true;
+ vnic->ff_pool_idx = 0;
+ vnic->start_grp_id = 0;
+ vnic->end_grp_id = vnic->start_grp_id;
+ filter = bnxt_alloc_filter(bp);
+ if (!filter) {
+ PMD_DRV_LOG(ERR, "L2 filter alloc failed\n");
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+ goto out;
+ }
+
+ /* Multi-queue mode */
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_VMDQ_DCB_RSS) {
+ /* VMDq ONLY, VMDq+RSS, VMDq+DCB, VMDq+DCB+RSS */
+
+ switch (dev_conf->rxmode.mq_mode) {
+ case ETH_MQ_RX_VMDQ_RSS:
+ case ETH_MQ_RX_VMDQ_ONLY:
+ /* FALLTHROUGH */
+ /* ETH_8/64_POOLs */
+ pools = conf->nb_queue_pools;
+ /* For each pool, allocate MACVLAN CFA rule & VNIC */
+ max_pools = RTE_MIN(bp->max_vnics,
+ RTE_MIN(bp->max_l2_ctx,
+ RTE_MIN(bp->max_rsscos_ctx,
+ ETH_64_POOLS)));
+ if (pools > max_pools)
+ pools = max_pools;
+ break;
+ case ETH_MQ_RX_RSS:
+ pools = 1;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Unsupported mq_mod %d\n",
+ dev_conf->rxmode.mq_mode);
+ rc = -EINVAL;
+ goto err_out;
+ }
+ }
+
+ nb_q_per_grp = bp->rx_cp_nr_rings / pools;
+ start_grp_id = 0;
+ end_grp_id = nb_q_per_grp;
+
+ for (i = 0; i < pools; i++) {
+ vnic = bnxt_alloc_vnic(bp);
+ if (!vnic) {
+ PMD_DRV_LOG(ERR, "VNIC alloc failed\n");
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ vnic->flags |= BNXT_VNIC_INFO_BCAST;
+ STAILQ_INSERT_TAIL(&bp->ff_pool[i], vnic, next);
+ bp->nr_vnics++;
+
+ for (j = 0; j < nb_q_per_grp; j++, ring_idx++) {
+ rxq = bp->eth_dev->data->rx_queues[ring_idx];
+ rxq->vnic = vnic;
+ }
+ if (i == 0) {
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_VMDQ_DCB) {
+ bp->eth_dev->data->promiscuous = 1;
+ vnic->flags |= BNXT_VNIC_INFO_PROMISC;
+ }
+ vnic->func_default = true;
+ }
+ vnic->ff_pool_idx = i;
+ vnic->start_grp_id = start_grp_id;
+ vnic->end_grp_id = end_grp_id;
+
+ if (i) {
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_VMDQ_DCB ||
+ !(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS))
+ vnic->rss_dflt_cr = true;
+ goto skip_filter_allocation;
+ }
+ filter = bnxt_alloc_filter(bp);
+ if (!filter) {
+ PMD_DRV_LOG(ERR, "L2 filter alloc failed\n");
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ /*
+ * TODO: Configure & associate CFA rule for
+ * each VNIC for each VMDq with MACVLAN, MACVLAN+TC
+ */
+ STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+
+skip_filter_allocation:
+ start_grp_id = end_grp_id;
+ end_grp_id += nb_q_per_grp;
+ }
+
+out:
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) {
+ struct rte_eth_rss_conf *rss = &dev_conf->rx_adv_conf.rss_conf;
+ uint16_t hash_type = 0;
+
+ if (bp->flags & BNXT_FLAG_UPDATE_HASH) {
+ rss = &bp->rss_conf;
+ bp->flags &= ~BNXT_FLAG_UPDATE_HASH;
+ }
+
+ if (rss->rss_hf & ETH_RSS_IPV4)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+ if (rss->rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
+ if (rss->rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
+ if (rss->rss_hf & ETH_RSS_IPV6)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+ if (rss->rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
+ if (rss->rss_hf & ETH_RSS_NONFRAG_IPV6_UDP)
+ hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
+
+ for (i = 0; i < bp->nr_vnics; i++) {
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ vnic->hash_type = hash_type;
+
+ /*
+ * Use the supplied key if the key length is
+ * acceptable and the rss_key is not NULL
+ */
+ if (rss->rss_key &&
+ rss->rss_key_len <= HW_HASH_KEY_SIZE)
+ memcpy(vnic->rss_hash_key,
+ rss->rss_key, rss->rss_key_len);
+ }
+ }
+ }
+
+ return rc;
+
+err_out:
+ /* Free allocated vnic/filters */
+
+ return rc;
+}
+
+void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq)
+{
+ struct bnxt_sw_rx_bd *sw_ring;
+ struct bnxt_tpa_info *tpa_info;
+ uint16_t i;
+
+ rte_spinlock_lock(&rxq->lock);
+
+ if (rxq) {
+ sw_ring = rxq->rx_ring->rx_buf_ring;
+ if (sw_ring) {
+ for (i = 0;
+ i < rxq->rx_ring->rx_ring_struct->ring_size; i++) {
+ if (sw_ring[i].mbuf) {
+ rte_pktmbuf_free_seg(sw_ring[i].mbuf);
+ sw_ring[i].mbuf = NULL;
+ }
+ }
+ }
+ /* Free up mbufs in Agg ring */
+ sw_ring = rxq->rx_ring->ag_buf_ring;
+ if (sw_ring) {
+ for (i = 0;
+ i < rxq->rx_ring->ag_ring_struct->ring_size; i++) {
+ if (sw_ring[i].mbuf) {
+ rte_pktmbuf_free_seg(sw_ring[i].mbuf);
+ sw_ring[i].mbuf = NULL;
+ }
+ }
+ }
+
+ /* Free up mbufs in TPA */
+ tpa_info = rxq->rx_ring->tpa_info;
+ if (tpa_info) {
+ for (i = 0; i < BNXT_TPA_MAX; i++) {
+ if (tpa_info[i].mbuf) {
+ rte_pktmbuf_free_seg(tpa_info[i].mbuf);
+ tpa_info[i].mbuf = NULL;
+ }
+ }
+ }
+ }
+
+ rte_spinlock_unlock(&rxq->lock);
+}
+
+void bnxt_free_rx_mbufs(struct bnxt *bp)
+{
+ struct bnxt_rx_queue *rxq;
+ int i;
+
+ for (i = 0; i < (int)bp->rx_nr_rings; i++) {
+ rxq = bp->rx_queues[i];
+ bnxt_rx_queue_release_mbufs(rxq);
+ }
+}
+
+void bnxt_rx_queue_release_op(void *rx_queue)
+{
+ struct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue;
+
+ if (rxq) {
+ bnxt_rx_queue_release_mbufs(rxq);
+
+ /* Free RX ring hardware descriptors */
+ bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
+ /* Free RX Agg ring hardware descriptors */
+ bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
+
+ /* Free RX completion ring hardware descriptors */
+ bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
+
+ bnxt_free_rxq_stats(rxq);
+ rte_memzone_free(rxq->mz);
+ rxq->mz = NULL;
+
+ rte_free(rxq);
+ }
+}
+
+int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
+ uint16_t queue_idx,
+ uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_rxconf *rx_conf,
+ struct rte_mempool *mp)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
+ struct bnxt_rx_queue *rxq;
+ int rc = 0;
+ uint8_t queue_state;
+
+ if (queue_idx >= bp->max_rx_rings) {
+ PMD_DRV_LOG(ERR,
+ "Cannot create Rx ring %d. Only %d rings available\n",
+ queue_idx, bp->max_rx_rings);
+ return -EINVAL;
+ }
+
+ if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) {
+ PMD_DRV_LOG(ERR, "nb_desc %d is invalid\n", nb_desc);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if (eth_dev->data->rx_queues) {
+ rxq = eth_dev->data->rx_queues[queue_idx];
+ if (rxq)
+ bnxt_rx_queue_release_op(rxq);
+ }
+ rxq = rte_zmalloc_socket("bnxt_rx_queue", sizeof(struct bnxt_rx_queue),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (!rxq) {
+ PMD_DRV_LOG(ERR, "bnxt_rx_queue allocation failed!\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ rxq->bp = bp;
+ rxq->mb_pool = mp;
+ rxq->nb_rx_desc = nb_desc;
+ rxq->rx_free_thresh = rx_conf->rx_free_thresh;
+
+ PMD_DRV_LOG(DEBUG, "RX Buf size is %d\n", rxq->rx_buf_use_size);
+ PMD_DRV_LOG(DEBUG, "RX Buf MTU %d\n", eth_dev->data->mtu);
+
+ rc = bnxt_init_rx_ring_struct(rxq, socket_id);
+ if (rc)
+ goto out;
+
+ rxq->queue_id = queue_idx;
+ rxq->port_id = eth_dev->data->port_id;
+ rxq->crc_len = rte_eth_dev_must_keep_crc(rx_offloads) ?
+ ETHER_CRC_LEN : 0;
+
+ eth_dev->data->rx_queues[queue_idx] = rxq;
+ /* Allocate RX ring hardware descriptors */
+ if (bnxt_alloc_rings(bp, queue_idx, NULL, rxq, rxq->cp_ring,
+ "rxr")) {
+ PMD_DRV_LOG(ERR,
+ "ring_dma_zone_reserve for rx_ring failed!\n");
+ bnxt_rx_queue_release_op(rxq);
+ rc = -ENOMEM;
+ goto out;
+ }
+ rte_atomic64_init(&rxq->rx_mbuf_alloc_fail);
+
+ rxq->rx_deferred_start = rx_conf->rx_deferred_start;
+ queue_state = rxq->rx_deferred_start ? RTE_ETH_QUEUE_STATE_STOPPED :
+ RTE_ETH_QUEUE_STATE_STARTED;
+ eth_dev->data->rx_queue_state[queue_idx] = queue_state;
+ rte_spinlock_init(&rxq->lock);
+out:
+ return rc;
+}
+
+int
+bnxt_rx_queue_intr_enable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id)
+{
+ struct bnxt_rx_queue *rxq;
+ struct bnxt_cp_ring_info *cpr;
+ int rc = 0;
+
+ if (eth_dev->data->rx_queues) {
+ rxq = eth_dev->data->rx_queues[queue_id];
+ if (!rxq) {
+ rc = -EINVAL;
+ return rc;
+ }
+ cpr = rxq->cp_ring;
+ B_CP_DB_ARM(cpr);
+ }
+ return rc;
+}
+
+int
+bnxt_rx_queue_intr_disable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id)
+{
+ struct bnxt_rx_queue *rxq;
+ struct bnxt_cp_ring_info *cpr;
+ int rc = 0;
+
+ if (eth_dev->data->rx_queues) {
+ rxq = eth_dev->data->rx_queues[queue_id];
+ if (!rxq) {
+ rc = -EINVAL;
+ return rc;
+ }
+ cpr = rxq->cp_ring;
+ B_CP_DB_DISARM(cpr);
+ }
+ return rc;
+}
+
+int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ struct bnxt_rx_queue *rxq = bp->rx_queues[rx_queue_id];
+ struct bnxt_vnic_info *vnic = NULL;
+ int rc = 0;
+
+ if (rxq == NULL) {
+ PMD_DRV_LOG(ERR, "Invalid Rx queue %d\n", rx_queue_id);
+ return -EINVAL;
+ }
+
+ dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
+
+ bnxt_free_hwrm_rx_ring(bp, rx_queue_id);
+ bnxt_alloc_hwrm_rx_ring(bp, rx_queue_id);
+ PMD_DRV_LOG(INFO, "Rx queue started %d\n", rx_queue_id);
+
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) {
+ vnic = rxq->vnic;
+
+ if (vnic->fw_grp_ids[rx_queue_id] != INVALID_HW_RING_ID)
+ return 0;
+
+ PMD_DRV_LOG(DEBUG,
+ "vnic = %p fw_grp_id = %d\n",
+ vnic, bp->grp_info[rx_queue_id].fw_grp_id);
+
+ vnic->fw_grp_ids[rx_queue_id] =
+ bp->grp_info[rx_queue_id].fw_grp_id;
+ rc = bnxt_vnic_rss_configure(bp, vnic);
+ }
+
+ if (rc == 0)
+ rxq->rx_deferred_start = false;
+
+ return rc;
+}
+
+int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ struct bnxt_vnic_info *vnic = NULL;
+ struct bnxt_rx_queue *rxq = NULL;
+ int rc = 0;
+
+ /* Rx CQ 0 also works as Default CQ for async notifications */
+ if (!rx_queue_id) {
+ PMD_DRV_LOG(ERR, "Cannot stop Rx queue id %d\n", rx_queue_id);
+ return -EINVAL;
+ }
+
+ rxq = bp->rx_queues[rx_queue_id];
+
+ if (rxq == NULL) {
+ PMD_DRV_LOG(ERR, "Invalid Rx queue %d\n", rx_queue_id);
+ return -EINVAL;
+ }
+
+ dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+ rxq->rx_deferred_start = true;
+ PMD_DRV_LOG(DEBUG, "Rx queue stopped\n");
+
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) {
+ vnic = rxq->vnic;
+ vnic->fw_grp_ids[rx_queue_id] = INVALID_HW_RING_ID;
+ rc = bnxt_vnic_rss_configure(bp, vnic);
+ }
+
+ if (rc == 0)
+ bnxt_rx_queue_release_mbufs(rxq);
+
+ return rc;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxq.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxq.h
new file mode 100644
index 00000000..e5d6001d
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxq.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_RQX_H_
+#define _BNXT_RQX_H_
+
+struct bnxt;
+struct bnxt_rx_ring_info;
+struct bnxt_cp_ring_info;
+struct bnxt_rx_queue {
+ rte_spinlock_t lock; /* Synchronize between rx_queue_stop
+ * and fast path
+ */
+ struct rte_mempool *mb_pool; /* mbuf pool for RX ring */
+ struct rte_mbuf *pkt_first_seg; /* 1st seg of pkt */
+ struct rte_mbuf *pkt_last_seg; /* Last seg of pkt */
+ uint64_t mbuf_initializer; /* val to init mbuf */
+ uint16_t nb_rx_desc; /* num of RX desc */
+ uint16_t rx_tail; /* cur val of RDT register */
+ uint16_t nb_rx_hold; /* num held free RX desc */
+ uint16_t rx_free_thresh; /* max free RX desc to hold */
+ uint16_t queue_id; /* RX queue index */
+ uint16_t reg_idx; /* RX queue register index */
+ uint16_t port_id; /* Device port identifier */
+ uint8_t crc_len; /* 0 if CRC stripped, 4 otherwise */
+ uint8_t rx_deferred_start; /* not in global dev start */
+
+ struct bnxt *bp;
+ int index;
+ struct bnxt_vnic_info *vnic;
+
+ uint32_t rx_buf_size;
+ uint32_t rx_buf_use_size; /* useable size */
+ struct bnxt_rx_ring_info *rx_ring;
+ struct bnxt_cp_ring_info *cp_ring;
+ rte_atomic64_t rx_mbuf_alloc_fail;
+ const struct rte_memzone *mz;
+};
+
+void bnxt_free_rxq_stats(struct bnxt_rx_queue *rxq);
+int bnxt_mq_rx_configure(struct bnxt *bp);
+void bnxt_rx_queue_release_op(void *rx_queue);
+int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
+ uint16_t queue_idx,
+ uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_rxconf *rx_conf,
+ struct rte_mempool *mp);
+void bnxt_free_rx_mbufs(struct bnxt *bp);
+int bnxt_rx_queue_intr_enable_op(struct rte_eth_dev *eth_dev,
+ uint16_t queue_id);
+int bnxt_rx_queue_intr_disable_op(struct rte_eth_dev *eth_dev,
+ uint16_t queue_id);
+int bnxt_rx_queue_start(struct rte_eth_dev *dev,
+ uint16_t rx_queue_id);
+int bnxt_rx_queue_stop(struct rte_eth_dev *dev,
+ uint16_t rx_queue_id);
+void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq);
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxr.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxr.c
new file mode 100644
index 00000000..c7bc8848
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxr.c
@@ -0,0 +1,805 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <rte_bitmap.h>
+#include <rte_byteorder.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_ring.h"
+#include "bnxt_rxr.h"
+#include "bnxt_rxq.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * RX Ring handling
+ */
+
+static inline struct rte_mbuf *__bnxt_alloc_rx_data(struct rte_mempool *mb)
+{
+ struct rte_mbuf *data;
+
+ data = rte_mbuf_raw_alloc(mb);
+
+ return data;
+}
+
+static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
+ struct bnxt_rx_ring_info *rxr,
+ uint16_t prod)
+{
+ struct rx_prod_pkt_bd *rxbd = &rxr->rx_desc_ring[prod];
+ struct bnxt_sw_rx_bd *rx_buf = &rxr->rx_buf_ring[prod];
+ struct rte_mbuf *mbuf;
+
+ mbuf = __bnxt_alloc_rx_data(rxq->mb_pool);
+ if (!mbuf) {
+ rte_atomic64_inc(&rxq->rx_mbuf_alloc_fail);
+ return -ENOMEM;
+ }
+
+ rx_buf->mbuf = mbuf;
+ mbuf->data_off = RTE_PKTMBUF_HEADROOM;
+
+ rxbd->address = rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf));
+
+ return 0;
+}
+
+static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
+ struct bnxt_rx_ring_info *rxr,
+ uint16_t prod)
+{
+ struct rx_prod_pkt_bd *rxbd = &rxr->ag_desc_ring[prod];
+ struct bnxt_sw_rx_bd *rx_buf = &rxr->ag_buf_ring[prod];
+ struct rte_mbuf *mbuf;
+
+ mbuf = __bnxt_alloc_rx_data(rxq->mb_pool);
+ if (!mbuf) {
+ rte_atomic64_inc(&rxq->rx_mbuf_alloc_fail);
+ return -ENOMEM;
+ }
+
+ if (rxbd == NULL)
+ PMD_DRV_LOG(ERR, "Jumbo Frame. rxbd is NULL\n");
+ if (rx_buf == NULL)
+ PMD_DRV_LOG(ERR, "Jumbo Frame. rx_buf is NULL\n");
+
+
+ rx_buf->mbuf = mbuf;
+ mbuf->data_off = RTE_PKTMBUF_HEADROOM;
+
+ rxbd->address = rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf));
+
+ return 0;
+}
+
+static inline void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr,
+ struct rte_mbuf *mbuf)
+{
+ uint16_t prod = RING_NEXT(rxr->rx_ring_struct, rxr->rx_prod);
+ struct bnxt_sw_rx_bd *prod_rx_buf;
+ struct rx_prod_pkt_bd *prod_bd;
+
+ prod_rx_buf = &rxr->rx_buf_ring[prod];
+
+ RTE_ASSERT(prod_rx_buf->mbuf == NULL);
+ RTE_ASSERT(mbuf != NULL);
+
+ prod_rx_buf->mbuf = mbuf;
+
+ prod_bd = &rxr->rx_desc_ring[prod];
+
+ prod_bd->address = rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf));
+
+ rxr->rx_prod = prod;
+}
+
+#ifdef BNXT_DEBUG
+static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
+ struct rte_mbuf *mbuf)
+{
+ uint16_t prod = rxr->ag_prod;
+ struct bnxt_sw_rx_bd *prod_rx_buf;
+ struct rx_prod_pkt_bd *prod_bd, *cons_bd;
+
+ prod_rx_buf = &rxr->ag_buf_ring[prod];
+
+ prod_rx_buf->mbuf = mbuf;
+
+ prod_bd = &rxr->ag_desc_ring[prod];
+ cons_bd = &rxr->ag_desc_ring[cons];
+
+ prod_bd->address = cons_bd->addr;
+}
+#endif
+
+static inline
+struct rte_mbuf *bnxt_consume_rx_buf(struct bnxt_rx_ring_info *rxr,
+ uint16_t cons)
+{
+ struct bnxt_sw_rx_bd *cons_rx_buf;
+ struct rte_mbuf *mbuf;
+
+ cons_rx_buf = &rxr->rx_buf_ring[cons];
+ RTE_ASSERT(cons_rx_buf->mbuf != NULL);
+ mbuf = cons_rx_buf->mbuf;
+ cons_rx_buf->mbuf = NULL;
+ return mbuf;
+}
+
+static void bnxt_tpa_start(struct bnxt_rx_queue *rxq,
+ struct rx_tpa_start_cmpl *tpa_start,
+ struct rx_tpa_start_cmpl_hi *tpa_start1)
+{
+ struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+ uint8_t agg_id = rte_le_to_cpu_32(tpa_start->agg_id &
+ RX_TPA_START_CMPL_AGG_ID_MASK) >> RX_TPA_START_CMPL_AGG_ID_SFT;
+ uint16_t data_cons;
+ struct bnxt_tpa_info *tpa_info;
+ struct rte_mbuf *mbuf;
+
+ data_cons = tpa_start->opaque;
+ tpa_info = &rxr->tpa_info[agg_id];
+
+ mbuf = bnxt_consume_rx_buf(rxr, data_cons);
+
+ bnxt_reuse_rx_mbuf(rxr, tpa_info->mbuf);
+
+ tpa_info->mbuf = mbuf;
+ tpa_info->len = rte_le_to_cpu_32(tpa_start->len);
+
+ mbuf->nb_segs = 1;
+ mbuf->next = NULL;
+ mbuf->pkt_len = rte_le_to_cpu_32(tpa_start->len);
+ mbuf->data_len = mbuf->pkt_len;
+ mbuf->port = rxq->port_id;
+ mbuf->ol_flags = PKT_RX_LRO;
+ if (likely(tpa_start->flags_type &
+ rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS_RSS_VALID))) {
+ mbuf->hash.rss = rte_le_to_cpu_32(tpa_start->rss_hash);
+ mbuf->ol_flags |= PKT_RX_RSS_HASH;
+ } else {
+ mbuf->hash.fdir.id = rte_le_to_cpu_16(tpa_start1->cfa_code);
+ mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
+ }
+ if (tpa_start1->flags2 &
+ rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN)) {
+ mbuf->vlan_tci = rte_le_to_cpu_32(tpa_start1->metadata);
+ mbuf->ol_flags |= PKT_RX_VLAN;
+ }
+ if (likely(tpa_start1->flags2 &
+ rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC)))
+ mbuf->ol_flags |= PKT_RX_L4_CKSUM_GOOD;
+
+ /* recycle next mbuf */
+ data_cons = RING_NEXT(rxr->rx_ring_struct, data_cons);
+ bnxt_reuse_rx_mbuf(rxr, bnxt_consume_rx_buf(rxr, data_cons));
+}
+
+static int bnxt_agg_bufs_valid(struct bnxt_cp_ring_info *cpr,
+ uint8_t agg_bufs, uint32_t raw_cp_cons)
+{
+ uint16_t last_cp_cons;
+ struct rx_pkt_cmpl *agg_cmpl;
+
+ raw_cp_cons = ADV_RAW_CMP(raw_cp_cons, agg_bufs);
+ last_cp_cons = RING_CMP(cpr->cp_ring_struct, raw_cp_cons);
+ agg_cmpl = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[last_cp_cons];
+ cpr->valid = FLIP_VALID(raw_cp_cons,
+ cpr->cp_ring_struct->ring_mask,
+ cpr->valid);
+ return CMP_VALID(agg_cmpl, raw_cp_cons, cpr->cp_ring_struct);
+}
+
+/* TPA consume agg buffer out of order, allocate connected data only */
+static int bnxt_prod_ag_mbuf(struct bnxt_rx_queue *rxq)
+{
+ struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+ uint16_t next = RING_NEXT(rxr->ag_ring_struct, rxr->ag_prod);
+
+ /* TODO batch allocation for better performance */
+ while (rte_bitmap_get(rxr->ag_bitmap, next)) {
+ if (unlikely(bnxt_alloc_ag_data(rxq, rxr, next))) {
+ PMD_DRV_LOG(ERR,
+ "agg mbuf alloc failed: prod=0x%x\n", next);
+ break;
+ }
+ rte_bitmap_clear(rxr->ag_bitmap, next);
+ rxr->ag_prod = next;
+ next = RING_NEXT(rxr->ag_ring_struct, next);
+ }
+
+ return 0;
+}
+
+static int bnxt_rx_pages(struct bnxt_rx_queue *rxq,
+ struct rte_mbuf *mbuf, uint32_t *tmp_raw_cons,
+ uint8_t agg_buf)
+{
+ struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+ struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+ int i;
+ uint16_t cp_cons, ag_cons;
+ struct rx_pkt_cmpl *rxcmp;
+ struct rte_mbuf *last = mbuf;
+
+ for (i = 0; i < agg_buf; i++) {
+ struct bnxt_sw_rx_bd *ag_buf;
+ struct rte_mbuf *ag_mbuf;
+ *tmp_raw_cons = NEXT_RAW_CMP(*tmp_raw_cons);
+ cp_cons = RING_CMP(cpr->cp_ring_struct, *tmp_raw_cons);
+ rxcmp = (struct rx_pkt_cmpl *)
+ &cpr->cp_desc_ring[cp_cons];
+
+#ifdef BNXT_DEBUG
+ bnxt_dump_cmpl(cp_cons, rxcmp);
+#endif
+
+ ag_cons = rxcmp->opaque;
+ RTE_ASSERT(ag_cons <= rxr->ag_ring_struct->ring_mask);
+ ag_buf = &rxr->ag_buf_ring[ag_cons];
+ ag_mbuf = ag_buf->mbuf;
+ RTE_ASSERT(ag_mbuf != NULL);
+
+ ag_mbuf->data_len = rte_le_to_cpu_16(rxcmp->len);
+
+ mbuf->nb_segs++;
+ mbuf->pkt_len += ag_mbuf->data_len;
+
+ last->next = ag_mbuf;
+ last = ag_mbuf;
+
+ ag_buf->mbuf = NULL;
+
+ /*
+ * As aggregation buffer consumed out of order in TPA module,
+ * use bitmap to track freed slots to be allocated and notified
+ * to NIC
+ */
+ rte_bitmap_set(rxr->ag_bitmap, ag_cons);
+ }
+ bnxt_prod_ag_mbuf(rxq);
+ return 0;
+}
+
+static inline struct rte_mbuf *bnxt_tpa_end(
+ struct bnxt_rx_queue *rxq,
+ uint32_t *raw_cp_cons,
+ struct rx_tpa_end_cmpl *tpa_end,
+ struct rx_tpa_end_cmpl_hi *tpa_end1 __rte_unused)
+{
+ struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+ struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+ uint8_t agg_id = (tpa_end->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK)
+ >> RX_TPA_END_CMPL_AGG_ID_SFT;
+ struct rte_mbuf *mbuf;
+ uint8_t agg_bufs;
+ struct bnxt_tpa_info *tpa_info;
+
+ tpa_info = &rxr->tpa_info[agg_id];
+ mbuf = tpa_info->mbuf;
+ RTE_ASSERT(mbuf != NULL);
+
+ rte_prefetch0(mbuf);
+ agg_bufs = (rte_le_to_cpu_32(tpa_end->agg_bufs_v1) &
+ RX_TPA_END_CMPL_AGG_BUFS_MASK) >> RX_TPA_END_CMPL_AGG_BUFS_SFT;
+ if (agg_bufs) {
+ if (!bnxt_agg_bufs_valid(cpr, agg_bufs, *raw_cp_cons))
+ return NULL;
+ bnxt_rx_pages(rxq, mbuf, raw_cp_cons, agg_bufs);
+ }
+ mbuf->l4_len = tpa_end->payload_offset;
+
+ struct rte_mbuf *new_data = __bnxt_alloc_rx_data(rxq->mb_pool);
+ RTE_ASSERT(new_data != NULL);
+ if (!new_data) {
+ rte_atomic64_inc(&rxq->rx_mbuf_alloc_fail);
+ return NULL;
+ }
+ tpa_info->mbuf = new_data;
+
+ return mbuf;
+}
+
+static uint32_t
+bnxt_parse_pkt_type(struct rx_pkt_cmpl *rxcmp, struct rx_pkt_cmpl_hi *rxcmp1)
+{
+ uint32_t l3, pkt_type = 0;
+ uint32_t t_ipcs = 0, ip6 = 0, vlan = 0;
+ uint32_t flags_type;
+
+ vlan = !!(rxcmp1->flags2 &
+ rte_cpu_to_le_32(RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN));
+ pkt_type |= vlan ? RTE_PTYPE_L2_ETHER_VLAN : RTE_PTYPE_L2_ETHER;
+
+ t_ipcs = !!(rxcmp1->flags2 &
+ rte_cpu_to_le_32(RX_PKT_CMPL_FLAGS2_T_IP_CS_CALC));
+ ip6 = !!(rxcmp1->flags2 &
+ rte_cpu_to_le_32(RX_PKT_CMPL_FLAGS2_IP_TYPE));
+
+ flags_type = rxcmp->flags_type &
+ rte_cpu_to_le_32(RX_PKT_CMPL_FLAGS_ITYPE_MASK);
+
+ if (!t_ipcs && !ip6)
+ l3 = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+ else if (!t_ipcs && ip6)
+ l3 = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+ else if (t_ipcs && !ip6)
+ l3 = RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN;
+ else
+ l3 = RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN;
+
+ switch (flags_type) {
+ case RTE_LE32(RX_PKT_CMPL_FLAGS_ITYPE_ICMP):
+ if (!t_ipcs)
+ pkt_type |= l3 | RTE_PTYPE_L4_ICMP;
+ else
+ pkt_type |= l3 | RTE_PTYPE_INNER_L4_ICMP;
+ break;
+
+ case RTE_LE32(RX_PKT_CMPL_FLAGS_ITYPE_TCP):
+ if (!t_ipcs)
+ pkt_type |= l3 | RTE_PTYPE_L4_TCP;
+ else
+ pkt_type |= l3 | RTE_PTYPE_INNER_L4_TCP;
+ break;
+
+ case RTE_LE32(RX_PKT_CMPL_FLAGS_ITYPE_UDP):
+ if (!t_ipcs)
+ pkt_type |= l3 | RTE_PTYPE_L4_UDP;
+ else
+ pkt_type |= l3 | RTE_PTYPE_INNER_L4_UDP;
+ break;
+
+ case RTE_LE32(RX_PKT_CMPL_FLAGS_ITYPE_IP):
+ pkt_type |= l3;
+ break;
+ }
+
+ return pkt_type;
+}
+
+static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
+ struct bnxt_rx_queue *rxq, uint32_t *raw_cons)
+{
+ struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+ struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+ struct rx_pkt_cmpl *rxcmp;
+ struct rx_pkt_cmpl_hi *rxcmp1;
+ uint32_t tmp_raw_cons = *raw_cons;
+ uint16_t cons, prod, cp_cons =
+ RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
+#ifdef BNXT_DEBUG
+ uint16_t ag_cons;
+#endif
+ struct rte_mbuf *mbuf;
+ int rc = 0;
+ uint8_t agg_buf = 0;
+ uint16_t cmp_type;
+
+ rxcmp = (struct rx_pkt_cmpl *)
+ &cpr->cp_desc_ring[cp_cons];
+
+ tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
+ cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
+ rxcmp1 = (struct rx_pkt_cmpl_hi *)&cpr->cp_desc_ring[cp_cons];
+
+ if (!CMP_VALID(rxcmp1, tmp_raw_cons, cpr->cp_ring_struct))
+ return -EBUSY;
+
+ cpr->valid = FLIP_VALID(cp_cons,
+ cpr->cp_ring_struct->ring_mask,
+ cpr->valid);
+
+ cmp_type = CMP_TYPE(rxcmp);
+ if (cmp_type == RX_TPA_START_CMPL_TYPE_RX_TPA_START) {
+ bnxt_tpa_start(rxq, (struct rx_tpa_start_cmpl *)rxcmp,
+ (struct rx_tpa_start_cmpl_hi *)rxcmp1);
+ rc = -EINVAL; /* Continue w/o new mbuf */
+ goto next_rx;
+ } else if (cmp_type == RX_TPA_END_CMPL_TYPE_RX_TPA_END) {
+ mbuf = bnxt_tpa_end(rxq, &tmp_raw_cons,
+ (struct rx_tpa_end_cmpl *)rxcmp,
+ (struct rx_tpa_end_cmpl_hi *)rxcmp1);
+ if (unlikely(!mbuf))
+ return -EBUSY;
+ *rx_pkt = mbuf;
+ goto next_rx;
+ } else if (cmp_type != 0x11) {
+ rc = -EINVAL;
+ goto next_rx;
+ }
+
+ agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
+ >> RX_PKT_CMPL_AGG_BUFS_SFT;
+ if (agg_buf && !bnxt_agg_bufs_valid(cpr, agg_buf, tmp_raw_cons))
+ return -EBUSY;
+
+ prod = rxr->rx_prod;
+
+ cons = rxcmp->opaque;
+ mbuf = bnxt_consume_rx_buf(rxr, cons);
+ if (mbuf == NULL)
+ return -EBUSY;
+
+ rte_prefetch0(mbuf);
+
+ mbuf->data_off = RTE_PKTMBUF_HEADROOM;
+ mbuf->nb_segs = 1;
+ mbuf->next = NULL;
+ mbuf->pkt_len = rxcmp->len;
+ mbuf->data_len = mbuf->pkt_len;
+ mbuf->port = rxq->port_id;
+ mbuf->ol_flags = 0;
+ if (rxcmp->flags_type & RX_PKT_CMPL_FLAGS_RSS_VALID) {
+ mbuf->hash.rss = rxcmp->rss_hash;
+ mbuf->ol_flags |= PKT_RX_RSS_HASH;
+ } else {
+ mbuf->hash.fdir.id = rxcmp1->cfa_code;
+ mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
+ }
+
+ if ((rxcmp->flags_type & rte_cpu_to_le_16(RX_PKT_CMPL_FLAGS_MASK)) ==
+ RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP)
+ mbuf->ol_flags |= PKT_RX_IEEE1588_PTP | PKT_RX_IEEE1588_TMST;
+
+ if (agg_buf)
+ bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf);
+
+ if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
+ mbuf->vlan_tci = rxcmp1->metadata &
+ (RX_PKT_CMPL_METADATA_VID_MASK |
+ RX_PKT_CMPL_METADATA_DE |
+ RX_PKT_CMPL_METADATA_PRI_MASK);
+ mbuf->ol_flags |= PKT_RX_VLAN;
+ }
+
+ if (likely(RX_CMP_IP_CS_OK(rxcmp1)))
+ mbuf->ol_flags |= PKT_RX_IP_CKSUM_GOOD;
+ else if (likely(RX_CMP_IP_CS_UNKNOWN(rxcmp1)))
+ mbuf->ol_flags |= PKT_RX_IP_CKSUM_UNKNOWN;
+ else
+ mbuf->ol_flags |= PKT_RX_IP_CKSUM_BAD;
+
+ if (likely(RX_CMP_L4_CS_OK(rxcmp1)))
+ mbuf->ol_flags |= PKT_RX_L4_CKSUM_GOOD;
+ else if (likely(RX_CMP_L4_CS_UNKNOWN(rxcmp1)))
+ mbuf->ol_flags |= PKT_RX_L4_CKSUM_UNKNOWN;
+ else
+ mbuf->ol_flags |= PKT_RX_L4_CKSUM_BAD;
+
+ mbuf->packet_type = bnxt_parse_pkt_type(rxcmp, rxcmp1);
+
+#ifdef BNXT_DEBUG
+ if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
+ /* Re-install the mbuf back to the rx ring */
+ bnxt_reuse_rx_mbuf(rxr, cons, mbuf);
+ if (agg_buf)
+ bnxt_reuse_ag_mbuf(rxr, ag_cons, mbuf);
+
+ rc = -EIO;
+ goto next_rx;
+ }
+#endif
+ /*
+ * TODO: Redesign this....
+ * If the allocation fails, the packet does not get received.
+ * Simply returning this will result in slowly falling behind
+ * on the producer ring buffers.
+ * Instead, "filling up" the producer just before ringing the
+ * doorbell could be a better solution since it will let the
+ * producer ring starve until memory is available again pushing
+ * the drops into hardware and getting them out of the driver
+ * allowing recovery to a full producer ring.
+ *
+ * This could also help with cache usage by preventing per-packet
+ * calls in favour of a tight loop with the same function being called
+ * in it.
+ */
+ prod = RING_NEXT(rxr->rx_ring_struct, prod);
+ if (bnxt_alloc_rx_data(rxq, rxr, prod)) {
+ PMD_DRV_LOG(ERR, "mbuf alloc failed with prod=0x%x\n", prod);
+ rc = -ENOMEM;
+ goto rx;
+ }
+ rxr->rx_prod = prod;
+ /*
+ * All MBUFs are allocated with the same size under DPDK,
+ * no optimization for rx_copy_thresh
+ */
+rx:
+ *rx_pkt = mbuf;
+
+next_rx:
+
+ *raw_cons = tmp_raw_cons;
+
+ return rc;
+}
+
+uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts)
+{
+ struct bnxt_rx_queue *rxq = rx_queue;
+ struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+ struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+ uint32_t raw_cons = cpr->cp_raw_cons;
+ uint32_t cons;
+ int nb_rx_pkts = 0;
+ struct rx_pkt_cmpl *rxcmp;
+ uint16_t prod = rxr->rx_prod;
+ uint16_t ag_prod = rxr->ag_prod;
+ int rc = 0;
+ bool evt = false;
+
+ /* If Rx Q was stopped return. RxQ0 cannot be stopped. */
+ if (unlikely(((rxq->rx_deferred_start ||
+ !rte_spinlock_trylock(&rxq->lock)) &&
+ rxq->queue_id)))
+ return 0;
+
+ /* Handle RX burst request */
+ while (1) {
+ cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
+ rte_prefetch0(&cpr->cp_desc_ring[cons]);
+ rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
+
+ if (!CMP_VALID(rxcmp, raw_cons, cpr->cp_ring_struct))
+ break;
+ cpr->valid = FLIP_VALID(cons,
+ cpr->cp_ring_struct->ring_mask,
+ cpr->valid);
+
+ /* TODO: Avoid magic numbers... */
+ if ((CMP_TYPE(rxcmp) & 0x30) == 0x10) {
+ rc = bnxt_rx_pkt(&rx_pkts[nb_rx_pkts], rxq, &raw_cons);
+ if (likely(!rc) || rc == -ENOMEM)
+ nb_rx_pkts++;
+ if (rc == -EBUSY) /* partial completion */
+ break;
+ } else {
+ evt =
+ bnxt_event_hwrm_resp_handler(rxq->bp,
+ (struct cmpl_base *)rxcmp);
+ }
+
+ raw_cons = NEXT_RAW_CMP(raw_cons);
+ if (nb_rx_pkts == nb_pkts || evt)
+ break;
+ /* Post some Rx buf early in case of larger burst processing */
+ if (nb_rx_pkts == BNXT_RX_POST_THRESH)
+ B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+ }
+
+ cpr->cp_raw_cons = raw_cons;
+ if (!nb_rx_pkts && !evt) {
+ /*
+ * For PMD, there is no need to keep on pushing to REARM
+ * the doorbell if there are no new completions
+ */
+ goto done;
+ }
+
+ if (prod != rxr->rx_prod)
+ B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+
+ /* Ring the AGG ring DB */
+ if (ag_prod != rxr->ag_prod)
+ B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+
+ /* Attempt to alloc Rx buf in case of a previous allocation failure. */
+ if (rc == -ENOMEM) {
+ int i;
+
+ for (i = prod; i <= nb_rx_pkts;
+ i = RING_NEXT(rxr->rx_ring_struct, i)) {
+ struct bnxt_sw_rx_bd *rx_buf = &rxr->rx_buf_ring[i];
+
+ /* Buffer already allocated for this index. */
+ if (rx_buf->mbuf != NULL)
+ continue;
+
+ /* This slot is empty. Alloc buffer for Rx */
+ if (!bnxt_alloc_rx_data(rxq, rxr, i)) {
+ rxr->rx_prod = i;
+ B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+ } else {
+ PMD_DRV_LOG(ERR, "Alloc mbuf failed\n");
+ break;
+ }
+ }
+ }
+
+done:
+ rte_spinlock_unlock(&rxq->lock);
+
+ return nb_rx_pkts;
+}
+
+void bnxt_free_rx_rings(struct bnxt *bp)
+{
+ int i;
+ struct bnxt_rx_queue *rxq;
+
+ if (!bp->rx_queues)
+ return;
+
+ for (i = 0; i < (int)bp->rx_nr_rings; i++) {
+ rxq = bp->rx_queues[i];
+ if (!rxq)
+ continue;
+
+ bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
+ rte_free(rxq->rx_ring->rx_ring_struct);
+
+ /* Free the Aggregator ring */
+ bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
+ rte_free(rxq->rx_ring->ag_ring_struct);
+ rxq->rx_ring->ag_ring_struct = NULL;
+
+ rte_free(rxq->rx_ring);
+
+ bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
+ rte_free(rxq->cp_ring->cp_ring_struct);
+ rte_free(rxq->cp_ring);
+
+ rte_free(rxq);
+ bp->rx_queues[i] = NULL;
+ }
+}
+
+int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id)
+{
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_rx_ring_info *rxr;
+ struct bnxt_ring *ring;
+
+ rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN + ETHER_CRC_LEN +
+ (2 * VLAN_TAG_SIZE);
+ rxq->rx_buf_size = rxq->rx_buf_use_size + sizeof(struct rte_mbuf);
+
+ rxr = rte_zmalloc_socket("bnxt_rx_ring",
+ sizeof(struct bnxt_rx_ring_info),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (rxr == NULL)
+ return -ENOMEM;
+ rxq->rx_ring = rxr;
+
+ ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+ sizeof(struct bnxt_ring),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (ring == NULL)
+ return -ENOMEM;
+ rxr->rx_ring_struct = ring;
+ ring->ring_size = rte_align32pow2(rxq->nb_rx_desc);
+ ring->ring_mask = ring->ring_size - 1;
+ ring->bd = (void *)rxr->rx_desc_ring;
+ ring->bd_dma = rxr->rx_desc_mapping;
+ ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_rx_bd);
+ ring->vmem = (void **)&rxr->rx_buf_ring;
+
+ cpr = rte_zmalloc_socket("bnxt_rx_ring",
+ sizeof(struct bnxt_cp_ring_info),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (cpr == NULL)
+ return -ENOMEM;
+ rxq->cp_ring = cpr;
+
+ ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+ sizeof(struct bnxt_ring),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (ring == NULL)
+ return -ENOMEM;
+ cpr->cp_ring_struct = ring;
+ ring->ring_size = rte_align32pow2(rxr->rx_ring_struct->ring_size *
+ (2 + AGG_RING_SIZE_FACTOR));
+ ring->ring_mask = ring->ring_size - 1;
+ ring->bd = (void *)cpr->cp_desc_ring;
+ ring->bd_dma = cpr->cp_desc_mapping;
+ ring->vmem_size = 0;
+ ring->vmem = NULL;
+
+ /* Allocate Aggregator rings */
+ ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+ sizeof(struct bnxt_ring),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (ring == NULL)
+ return -ENOMEM;
+ rxr->ag_ring_struct = ring;
+ ring->ring_size = rte_align32pow2(rxq->nb_rx_desc *
+ AGG_RING_SIZE_FACTOR);
+ ring->ring_mask = ring->ring_size - 1;
+ ring->bd = (void *)rxr->ag_desc_ring;
+ ring->bd_dma = rxr->ag_desc_mapping;
+ ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_rx_bd);
+ ring->vmem = (void **)&rxr->ag_buf_ring;
+
+ return 0;
+}
+
+static void bnxt_init_rxbds(struct bnxt_ring *ring, uint32_t type,
+ uint16_t len)
+{
+ uint32_t j;
+ struct rx_prod_pkt_bd *rx_bd_ring = (struct rx_prod_pkt_bd *)ring->bd;
+
+ if (!rx_bd_ring)
+ return;
+ for (j = 0; j < ring->ring_size; j++) {
+ rx_bd_ring[j].flags_type = rte_cpu_to_le_16(type);
+ rx_bd_ring[j].len = rte_cpu_to_le_16(len);
+ rx_bd_ring[j].opaque = j;
+ }
+}
+
+int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
+{
+ struct bnxt_rx_ring_info *rxr;
+ struct bnxt_ring *ring;
+ uint32_t prod, type;
+ unsigned int i;
+ uint16_t size;
+
+ size = rte_pktmbuf_data_room_size(rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
+ if (rxq->rx_buf_use_size <= size)
+ size = rxq->rx_buf_use_size;
+
+ type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT | RX_PROD_PKT_BD_FLAGS_EOP_PAD;
+
+ rxr = rxq->rx_ring;
+ ring = rxr->rx_ring_struct;
+ bnxt_init_rxbds(ring, type, size);
+
+ prod = rxr->rx_prod;
+ for (i = 0; i < ring->ring_size; i++) {
+ if (bnxt_alloc_rx_data(rxq, rxr, prod) != 0) {
+ PMD_DRV_LOG(WARNING,
+ "init'ed rx ring %d with %d/%d mbufs only\n",
+ rxq->queue_id, i, ring->ring_size);
+ break;
+ }
+ rxr->rx_prod = prod;
+ prod = RING_NEXT(rxr->rx_ring_struct, prod);
+ }
+
+ ring = rxr->ag_ring_struct;
+ type = RX_PROD_AGG_BD_TYPE_RX_PROD_AGG;
+ bnxt_init_rxbds(ring, type, size);
+ prod = rxr->ag_prod;
+
+ for (i = 0; i < ring->ring_size; i++) {
+ if (bnxt_alloc_ag_data(rxq, rxr, prod) != 0) {
+ PMD_DRV_LOG(WARNING,
+ "init'ed AG ring %d with %d/%d mbufs only\n",
+ rxq->queue_id, i, ring->ring_size);
+ break;
+ }
+ rxr->ag_prod = prod;
+ prod = RING_NEXT(rxr->ag_ring_struct, prod);
+ }
+ PMD_DRV_LOG(DEBUG, "AGG Done!\n");
+
+ if (rxr->tpa_info) {
+ for (i = 0; i < BNXT_TPA_MAX; i++) {
+ rxr->tpa_info[i].mbuf =
+ __bnxt_alloc_rx_data(rxq->mb_pool);
+ if (!rxr->tpa_info[i].mbuf) {
+ rte_atomic64_inc(&rxq->rx_mbuf_alloc_fail);
+ return -ENOMEM;
+ }
+ }
+ }
+ PMD_DRV_LOG(DEBUG, "TPA alloc Done!\n");
+
+ return 0;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxr.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxr.h
new file mode 100644
index 00000000..3815a219
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_rxr.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_RXR_H_
+#define _BNXT_RXR_H_
+
+#define B_RX_DB(db, prod) \
+ (*(uint32_t *)db = (DB_KEY_RX | prod))
+
+#define BNXT_TPA_L4_SIZE(x) \
+ { \
+ typeof(x) hdr_info = (x); \
+ (((hdr_info) & 0xf8000000) ? ((hdr_info) >> 27) : 32) \
+ }
+
+#define BNXT_TPA_INNER_L3_OFF(hdr_info) \
+ (((hdr_info) >> 18) & 0x1ff)
+
+#define BNXT_TPA_INNER_L2_OFF(hdr_info) \
+ (((hdr_info) >> 9) & 0x1ff)
+
+#define BNXT_TPA_OUTER_L3_OFF(hdr_info) \
+ ((hdr_info) & 0x1ff)
+
+#define RX_CMP_L4_CS_BITS \
+ rte_cpu_to_le_32(RX_PKT_CMPL_FLAGS2_L4_CS_CALC | \
+ RX_PKT_CMPL_FLAGS2_T_L4_CS_CALC)
+
+#define RX_CMP_L4_CS_ERR_BITS \
+ rte_cpu_to_le_32(RX_PKT_CMPL_ERRORS_L4_CS_ERROR | \
+ RX_PKT_CMPL_ERRORS_T_L4_CS_ERROR)
+
+#define RX_CMP_L4_CS_OK(rxcmp1) \
+ (((rxcmp1)->flags2 & RX_CMP_L4_CS_BITS) && \
+ !((rxcmp1)->errors_v2 & RX_CMP_L4_CS_ERR_BITS))
+
+#define RX_CMP_L4_CS_UNKNOWN(rxcmp1) \
+ !((rxcmp1)->flags2 & RX_CMP_L4_CS_BITS)
+
+#define RX_CMP_IP_CS_ERR_BITS \
+ rte_cpu_to_le_32(RX_PKT_CMPL_ERRORS_IP_CS_ERROR | \
+ RX_PKT_CMPL_ERRORS_T_IP_CS_ERROR)
+
+#define RX_CMP_IP_CS_BITS \
+ rte_cpu_to_le_32(RX_PKT_CMPL_FLAGS2_IP_CS_CALC | \
+ RX_PKT_CMPL_FLAGS2_T_IP_CS_CALC)
+
+#define RX_CMP_IP_CS_OK(rxcmp1) \
+ (((rxcmp1)->flags2 & RX_CMP_IP_CS_BITS) && \
+ !((rxcmp1)->errors_v2 & RX_CMP_IP_CS_ERR_BITS))
+
+#define RX_CMP_IP_CS_UNKNOWN(rxcmp1) \
+ !((rxcmp1)->flags2 & RX_CMP_IP_CS_BITS)
+
+#define BNXT_RX_POST_THRESH 32
+
+enum pkt_hash_types {
+ PKT_HASH_TYPE_NONE, /* Undefined type */
+ PKT_HASH_TYPE_L2, /* Input: src_MAC, dest_MAC */
+ PKT_HASH_TYPE_L3, /* Input: src_IP, dst_IP */
+ PKT_HASH_TYPE_L4, /* Input: src_IP, dst_IP, src_port, dst_port */
+};
+
+struct bnxt_tpa_info {
+ struct rte_mbuf *mbuf;
+ uint16_t len;
+ unsigned short gso_type;
+ uint32_t flags2;
+ uint32_t metadata;
+ enum pkt_hash_types hash_type;
+ uint32_t rss_hash;
+ uint32_t hdr_info;
+};
+
+struct bnxt_sw_rx_bd {
+ struct rte_mbuf *mbuf; /* data associated with RX descriptor */
+};
+
+struct bnxt_rx_ring_info {
+ uint16_t rx_prod;
+ uint16_t ag_prod;
+ void *rx_doorbell;
+ void *ag_doorbell;
+
+ struct rx_prod_pkt_bd *rx_desc_ring;
+ struct rx_prod_pkt_bd *ag_desc_ring;
+ struct bnxt_sw_rx_bd *rx_buf_ring; /* sw ring */
+ struct bnxt_sw_rx_bd *ag_buf_ring; /* sw ring */
+
+ rte_iova_t rx_desc_mapping;
+ rte_iova_t ag_desc_mapping;
+
+ struct bnxt_ring *rx_ring_struct;
+ struct bnxt_ring *ag_ring_struct;
+
+ /*
+ * To deal with out of order return from TPA, use free buffer indicator
+ */
+ struct rte_bitmap *ag_bitmap;
+
+ struct bnxt_tpa_info *tpa_info;
+};
+
+uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts);
+void bnxt_free_rx_rings(struct bnxt *bp);
+int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id);
+int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq);
+int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
+int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_stats.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_stats.c
new file mode 100644
index 00000000..a5d3c866
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_stats.c
@@ -0,0 +1,406 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+
+#include <rte_byteorder.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_rxq.h"
+#include "bnxt_stats.h"
+#include "bnxt_txq.h"
+#include "hsi_struct_def_dpdk.h"
+
+static const struct bnxt_xstats_name_off bnxt_rx_stats_strings[] = {
+ {"rx_64b_frames", offsetof(struct rx_port_stats,
+ rx_64b_frames)},
+ {"rx_65b_127b_frames", offsetof(struct rx_port_stats,
+ rx_65b_127b_frames)},
+ {"rx_128b_255b_frames", offsetof(struct rx_port_stats,
+ rx_128b_255b_frames)},
+ {"rx_256b_511b_frames", offsetof(struct rx_port_stats,
+ rx_256b_511b_frames)},
+ {"rx_512b_1023b_frames", offsetof(struct rx_port_stats,
+ rx_512b_1023b_frames)},
+ {"rx_1024b_1518_frames", offsetof(struct rx_port_stats,
+ rx_1024b_1518_frames)},
+ {"rx_good_vlan_frames", offsetof(struct rx_port_stats,
+ rx_good_vlan_frames)},
+ {"rx_1519b_2047b_frames", offsetof(struct rx_port_stats,
+ rx_1519b_2047b_frames)},
+ {"rx_2048b_4095b_frames", offsetof(struct rx_port_stats,
+ rx_2048b_4095b_frames)},
+ {"rx_4096b_9216b_frames", offsetof(struct rx_port_stats,
+ rx_4096b_9216b_frames)},
+ {"rx_9217b_16383b_frames", offsetof(struct rx_port_stats,
+ rx_9217b_16383b_frames)},
+ {"rx_total_frames", offsetof(struct rx_port_stats,
+ rx_total_frames)},
+ {"rx_ucast_frames", offsetof(struct rx_port_stats,
+ rx_ucast_frames)},
+ {"rx_mcast_frames", offsetof(struct rx_port_stats,
+ rx_mcast_frames)},
+ {"rx_bcast_frames", offsetof(struct rx_port_stats,
+ rx_bcast_frames)},
+ {"rx_fcs_err_frames", offsetof(struct rx_port_stats,
+ rx_fcs_err_frames)},
+ {"rx_ctrl_frames", offsetof(struct rx_port_stats,
+ rx_ctrl_frames)},
+ {"rx_pause_frames", offsetof(struct rx_port_stats,
+ rx_pause_frames)},
+ {"rx_pfc_frames", offsetof(struct rx_port_stats,
+ rx_pfc_frames)},
+ {"rx_align_err_frames", offsetof(struct rx_port_stats,
+ rx_align_err_frames)},
+ {"rx_ovrsz_frames", offsetof(struct rx_port_stats,
+ rx_ovrsz_frames)},
+ {"rx_jbr_frames", offsetof(struct rx_port_stats,
+ rx_jbr_frames)},
+ {"rx_mtu_err_frames", offsetof(struct rx_port_stats,
+ rx_mtu_err_frames)},
+ {"rx_tagged_frames", offsetof(struct rx_port_stats,
+ rx_tagged_frames)},
+ {"rx_double_tagged_frames", offsetof(struct rx_port_stats,
+ rx_double_tagged_frames)},
+ {"rx_good_frames", offsetof(struct rx_port_stats,
+ rx_good_frames)},
+ {"rx_undrsz_frames", offsetof(struct rx_port_stats,
+ rx_undrsz_frames)},
+ {"rx_eee_lpi_events", offsetof(struct rx_port_stats,
+ rx_eee_lpi_events)},
+ {"rx_eee_lpi_duration", offsetof(struct rx_port_stats,
+ rx_eee_lpi_duration)},
+ {"rx_bytes", offsetof(struct rx_port_stats,
+ rx_bytes)},
+ {"rx_runt_bytes", offsetof(struct rx_port_stats,
+ rx_runt_bytes)},
+ {"rx_runt_frames", offsetof(struct rx_port_stats,
+ rx_runt_frames)},
+};
+
+static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
+ {"tx_64b_frames", offsetof(struct tx_port_stats,
+ tx_64b_frames)},
+ {"tx_65b_127b_frames", offsetof(struct tx_port_stats,
+ tx_65b_127b_frames)},
+ {"tx_128b_255b_frames", offsetof(struct tx_port_stats,
+ tx_128b_255b_frames)},
+ {"tx_256b_511b_frames", offsetof(struct tx_port_stats,
+ tx_256b_511b_frames)},
+ {"tx_512b_1023b_frames", offsetof(struct tx_port_stats,
+ tx_512b_1023b_frames)},
+ {"tx_1024b_1518_frames", offsetof(struct tx_port_stats,
+ tx_1024b_1518_frames)},
+ {"tx_good_vlan_frames", offsetof(struct tx_port_stats,
+ tx_good_vlan_frames)},
+ {"tx_1519b_2047_frames", offsetof(struct tx_port_stats,
+ tx_1519b_2047_frames)},
+ {"tx_2048b_4095b_frames", offsetof(struct tx_port_stats,
+ tx_2048b_4095b_frames)},
+ {"tx_4096b_9216b_frames", offsetof(struct tx_port_stats,
+ tx_4096b_9216b_frames)},
+ {"tx_9217b_16383b_frames", offsetof(struct tx_port_stats,
+ tx_9217b_16383b_frames)},
+ {"tx_good_frames", offsetof(struct tx_port_stats,
+ tx_good_frames)},
+ {"tx_total_frames", offsetof(struct tx_port_stats,
+ tx_total_frames)},
+ {"tx_ucast_frames", offsetof(struct tx_port_stats,
+ tx_ucast_frames)},
+ {"tx_mcast_frames", offsetof(struct tx_port_stats,
+ tx_mcast_frames)},
+ {"tx_bcast_frames", offsetof(struct tx_port_stats,
+ tx_bcast_frames)},
+ {"tx_pause_frames", offsetof(struct tx_port_stats,
+ tx_pause_frames)},
+ {"tx_pfc_frames", offsetof(struct tx_port_stats,
+ tx_pfc_frames)},
+ {"tx_jabber_frames", offsetof(struct tx_port_stats,
+ tx_jabber_frames)},
+ {"tx_fcs_err_frames", offsetof(struct tx_port_stats,
+ tx_fcs_err_frames)},
+ {"tx_err", offsetof(struct tx_port_stats,
+ tx_err)},
+ {"tx_fifo_underruns", offsetof(struct tx_port_stats,
+ tx_fifo_underruns)},
+ {"tx_eee_lpi_events", offsetof(struct tx_port_stats,
+ tx_eee_lpi_events)},
+ {"tx_eee_lpi_duration", offsetof(struct tx_port_stats,
+ tx_eee_lpi_duration)},
+ {"tx_total_collisions", offsetof(struct tx_port_stats,
+ tx_total_collisions)},
+ {"tx_bytes", offsetof(struct tx_port_stats,
+ tx_bytes)},
+};
+
+static const struct bnxt_xstats_name_off bnxt_func_stats_strings[] = {
+ {"tx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
+ tx_ucast_pkts)},
+ {"tx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
+ tx_mcast_pkts)},
+ {"tx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
+ tx_bcast_pkts)},
+ {"tx_discard_pkts", offsetof(struct hwrm_func_qstats_output,
+ tx_discard_pkts)},
+ {"tx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
+ tx_drop_pkts)},
+ {"tx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
+ tx_ucast_bytes)},
+ {"tx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
+ tx_mcast_bytes)},
+ {"tx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
+ tx_bcast_bytes)},
+ {"rx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
+ rx_ucast_pkts)},
+ {"rx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
+ rx_mcast_pkts)},
+ {"rx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
+ rx_bcast_pkts)},
+ {"rx_discard_pkts", offsetof(struct hwrm_func_qstats_output,
+ rx_discard_pkts)},
+ {"rx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
+ rx_drop_pkts)},
+ {"rx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
+ rx_ucast_bytes)},
+ {"rx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
+ rx_mcast_bytes)},
+ {"rx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
+ rx_bcast_bytes)},
+ {"rx_agg_pkts", offsetof(struct hwrm_func_qstats_output,
+ rx_agg_pkts)},
+ {"rx_agg_bytes", offsetof(struct hwrm_func_qstats_output,
+ rx_agg_bytes)},
+ {"rx_agg_events", offsetof(struct hwrm_func_qstats_output,
+ rx_agg_events)},
+ {"rx_agg_aborts", offsetof(struct hwrm_func_qstats_output,
+ rx_agg_aborts)},
+};
+
+/*
+ * Statistics functions
+ */
+
+void bnxt_free_stats(struct bnxt *bp)
+{
+ int i;
+
+ for (i = 0; i < (int)bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+
+ bnxt_free_txq_stats(txq);
+ }
+ for (i = 0; i < (int)bp->rx_cp_nr_rings; i++) {
+ struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+
+ bnxt_free_rxq_stats(rxq);
+ }
+}
+
+int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_stats *bnxt_stats)
+{
+ int rc = 0;
+ unsigned int i;
+ struct bnxt *bp = eth_dev->data->dev_private;
+
+ memset(bnxt_stats, 0, sizeof(*bnxt_stats));
+ if (!(bp->flags & BNXT_FLAG_INIT_DONE)) {
+ PMD_DRV_LOG(ERR, "Device Initialization not complete!\n");
+ return -1;
+ }
+
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+ struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+
+ rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
+ bnxt_stats, 1);
+ if (unlikely(rc))
+ return rc;
+ bnxt_stats->rx_nombuf +=
+ rte_atomic64_read(&rxq->rx_mbuf_alloc_fail);
+ }
+
+ for (i = 0; i < bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+ struct bnxt_cp_ring_info *cpr = txq->cp_ring;
+
+ rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
+ bnxt_stats, 0);
+ if (unlikely(rc))
+ return rc;
+ }
+ rc = bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats);
+ if (unlikely(rc))
+ return rc;
+ return rc;
+}
+
+void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ unsigned int i;
+
+ if (!(bp->flags & BNXT_FLAG_INIT_DONE)) {
+ PMD_DRV_LOG(ERR, "Device Initialization not complete!\n");
+ return;
+ }
+
+ bnxt_clear_all_hwrm_stat_ctxs(bp);
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+
+ rte_atomic64_clear(&rxq->rx_mbuf_alloc_fail);
+ }
+}
+
+int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_xstat *xstats, unsigned int n)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ unsigned int count, i;
+ uint64_t tx_drop_pkts;
+
+ bnxt_hwrm_port_qstats(bp);
+ bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, &tx_drop_pkts);
+
+ count = RTE_DIM(bnxt_rx_stats_strings) +
+ RTE_DIM(bnxt_tx_stats_strings) + 1; /* For tx_drop_pkts */
+
+ if (n < count)
+ return count;
+
+ count = 0;
+ for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
+ uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
+ xstats[count].id = count;
+ xstats[count].value = rte_le_to_cpu_64(
+ *(uint64_t *)((char *)rx_stats +
+ bnxt_rx_stats_strings[i].offset));
+ count++;
+ }
+
+ for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
+ uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
+ xstats[count].id = count;
+ xstats[count].value = rte_le_to_cpu_64(
+ *(uint64_t *)((char *)tx_stats +
+ bnxt_tx_stats_strings[i].offset));
+ count++;
+ }
+
+ /* The Tx drop pkts aka the Anti spoof coounter */
+ xstats[count].id = count;
+ xstats[count].value = rte_le_to_cpu_64(tx_drop_pkts);
+ count++;
+
+ return count;
+}
+
+int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
+ struct rte_eth_xstat_name *xstats_names,
+ __rte_unused unsigned int limit)
+{
+ /* Account for the Tx drop pkts aka the Anti spoof counter */
+ const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
+ RTE_DIM(bnxt_tx_stats_strings) + 1;
+ unsigned int i, count;
+
+ if (xstats_names != NULL) {
+ count = 0;
+
+ for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "%s",
+ bnxt_rx_stats_strings[i].name);
+ count++;
+ }
+
+ for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "%s",
+ bnxt_tx_stats_strings[i].name);
+ count++;
+ }
+
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "%s",
+ bnxt_func_stats_strings[4].name);
+ count++;
+ }
+ return stat_cnt;
+}
+
+void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ if (bp->flags & BNXT_FLAG_PORT_STATS && BNXT_SINGLE_PF(bp))
+ bnxt_hwrm_port_clr_stats(bp);
+
+ if (BNXT_VF(bp))
+ PMD_DRV_LOG(ERR, "Operation not supported on a VF device\n");
+ if (!BNXT_SINGLE_PF(bp))
+ PMD_DRV_LOG(ERR, "Operation not supported on a MF device\n");
+ if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+ PMD_DRV_LOG(ERR, "Operation not supported\n");
+}
+
+int bnxt_dev_xstats_get_by_id_op(struct rte_eth_dev *dev, const uint64_t *ids,
+ uint64_t *values, unsigned int limit)
+{
+ /* Account for the Tx drop pkts aka the Anti spoof counter */
+ const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
+ RTE_DIM(bnxt_tx_stats_strings) + 1;
+ struct rte_eth_xstat xstats[stat_cnt];
+ uint64_t values_copy[stat_cnt];
+ uint16_t i;
+
+ if (!ids)
+ return bnxt_dev_xstats_get_op(dev, xstats, stat_cnt);
+
+ bnxt_dev_xstats_get_by_id_op(dev, NULL, values_copy, stat_cnt);
+ for (i = 0; i < limit; i++) {
+ if (ids[i] >= stat_cnt) {
+ PMD_DRV_LOG(ERR, "id value isn't valid");
+ return -1;
+ }
+ values[i] = values_copy[ids[i]];
+ }
+ return stat_cnt;
+}
+
+int bnxt_dev_xstats_get_names_by_id_op(struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ const uint64_t *ids, unsigned int limit)
+{
+ /* Account for the Tx drop pkts aka the Anti spoof counter */
+ const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
+ RTE_DIM(bnxt_tx_stats_strings) + 1;
+ struct rte_eth_xstat_name xstats_names_copy[stat_cnt];
+ uint16_t i;
+
+ if (!ids)
+ return bnxt_dev_xstats_get_names_op(dev, xstats_names,
+ stat_cnt);
+ bnxt_dev_xstats_get_names_by_id_op(dev, xstats_names_copy, NULL,
+ stat_cnt);
+
+ for (i = 0; i < limit; i++) {
+ if (ids[i] >= stat_cnt) {
+ PMD_DRV_LOG(ERR, "id value isn't valid");
+ return -1;
+ }
+ strcpy(xstats_names[i].name,
+ xstats_names_copy[ids[i]].name);
+ }
+ return stat_cnt;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_stats.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_stats.h
new file mode 100644
index 00000000..b0f135a5
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_stats.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_STATS_H_
+#define _BNXT_STATS_H_
+
+#include <rte_ethdev_driver.h>
+
+void bnxt_free_stats(struct bnxt *bp);
+int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_stats *bnxt_stats);
+void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev);
+int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
+ struct rte_eth_xstat_name *xstats_names,
+ __rte_unused unsigned int limit);
+int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_xstat *xstats, unsigned int n);
+void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev);
+int bnxt_dev_xstats_get_by_id_op(struct rte_eth_dev *dev, const uint64_t *ids,
+ uint64_t *values, unsigned int limit);
+int bnxt_dev_xstats_get_names_by_id_op(struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ const uint64_t *ids, unsigned int limit);
+
+struct bnxt_xstats_name_off {
+ char name[RTE_ETH_XSTATS_NAME_SIZE];
+ uint64_t offset;
+};
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_txq.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_txq.c
new file mode 100644
index 00000000..b9b975e4
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_txq.c
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_ring.h"
+#include "bnxt_txq.h"
+#include "bnxt_txr.h"
+
+/*
+ * TX Queues
+ */
+
+void bnxt_free_txq_stats(struct bnxt_tx_queue *txq)
+{
+ if (txq && txq->cp_ring && txq->cp_ring->hw_stats)
+ txq->cp_ring->hw_stats = NULL;
+}
+
+static void bnxt_tx_queue_release_mbufs(struct bnxt_tx_queue *txq)
+{
+ struct bnxt_sw_tx_bd *sw_ring;
+ uint16_t i;
+
+ if (!txq)
+ return;
+
+ sw_ring = txq->tx_ring->tx_buf_ring;
+ if (sw_ring) {
+ for (i = 0; i < txq->tx_ring->tx_ring_struct->ring_size; i++) {
+ if (sw_ring[i].mbuf) {
+ rte_pktmbuf_free(sw_ring[i].mbuf);
+ sw_ring[i].mbuf = NULL;
+ }
+ }
+ }
+}
+
+void bnxt_free_tx_mbufs(struct bnxt *bp)
+{
+ struct bnxt_tx_queue *txq;
+ int i;
+
+ for (i = 0; i < (int)bp->tx_nr_rings; i++) {
+ txq = bp->tx_queues[i];
+ bnxt_tx_queue_release_mbufs(txq);
+ }
+}
+
+void bnxt_tx_queue_release_op(void *tx_queue)
+{
+ struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue;
+
+ if (txq) {
+ /* Free TX ring hardware descriptors */
+ bnxt_tx_queue_release_mbufs(txq);
+ bnxt_free_ring(txq->tx_ring->tx_ring_struct);
+
+ /* Free TX completion ring hardware descriptors */
+ bnxt_free_ring(txq->cp_ring->cp_ring_struct);
+
+ bnxt_free_txq_stats(txq);
+ rte_memzone_free(txq->mz);
+ txq->mz = NULL;
+
+ rte_free(txq);
+ }
+}
+
+int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
+ uint16_t queue_idx,
+ uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_tx_queue *txq;
+ int rc = 0;
+
+ if (queue_idx >= bp->max_tx_rings) {
+ PMD_DRV_LOG(ERR,
+ "Cannot create Tx ring %d. Only %d rings available\n",
+ queue_idx, bp->max_tx_rings);
+ return -EINVAL;
+ }
+
+ if (!nb_desc || nb_desc > MAX_TX_DESC_CNT) {
+ PMD_DRV_LOG(ERR, "nb_desc %d is invalid", nb_desc);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if (eth_dev->data->tx_queues) {
+ txq = eth_dev->data->tx_queues[queue_idx];
+ if (txq) {
+ bnxt_tx_queue_release_op(txq);
+ txq = NULL;
+ }
+ }
+ txq = rte_zmalloc_socket("bnxt_tx_queue", sizeof(struct bnxt_tx_queue),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (!txq) {
+ PMD_DRV_LOG(ERR, "bnxt_tx_queue allocation failed!");
+ rc = -ENOMEM;
+ goto out;
+ }
+ txq->bp = bp;
+ txq->nb_tx_desc = nb_desc;
+ txq->tx_free_thresh = tx_conf->tx_free_thresh;
+
+ rc = bnxt_init_tx_ring_struct(txq, socket_id);
+ if (rc)
+ goto out;
+
+ txq->queue_id = queue_idx;
+ txq->port_id = eth_dev->data->port_id;
+
+ /* Allocate TX ring hardware descriptors */
+ if (bnxt_alloc_rings(bp, queue_idx, txq, NULL, txq->cp_ring,
+ "txr")) {
+ PMD_DRV_LOG(ERR, "ring_dma_zone_reserve for tx_ring failed!");
+ bnxt_tx_queue_release_op(txq);
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ if (bnxt_init_one_tx_ring(txq)) {
+ PMD_DRV_LOG(ERR, "bnxt_init_one_tx_ring failed!");
+ bnxt_tx_queue_release_op(txq);
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ eth_dev->data->tx_queues[queue_idx] = txq;
+
+out:
+ return rc;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_txq.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_txq.h
new file mode 100644
index 00000000..f2c712a7
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_txq.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_TXQ_H_
+#define _BNXT_TXQ_H_
+
+struct bnxt_tx_ring_info;
+struct bnxt_cp_ring_info;
+struct bnxt_tx_queue {
+ uint16_t nb_tx_desc; /* number of TX descriptors */
+ uint16_t tx_free_thresh;/* minimum TX before freeing */
+ /** Index to last TX descriptor to have been cleaned. */
+ uint16_t last_desc_cleaned;
+ /** Total number of TX descriptors ready to be allocated. */
+ uint16_t tx_next_dd; /* next desc to scan for DD bit */
+ uint16_t tx_next_rs; /* next desc to set RS bit */
+ uint16_t queue_id; /* TX queue index */
+ uint16_t reg_idx; /* TX queue register index */
+ uint16_t port_id; /* Device port identifier */
+ uint8_t pthresh; /* Prefetch threshold register */
+ uint8_t hthresh; /* Host threshold register */
+ uint8_t wthresh; /* Write-back threshold reg */
+ uint32_t ctx_curr; /* Hardware context states */
+ uint8_t tx_deferred_start; /* not in global dev start */
+ uint8_t cmpl_next; /* Next BD to trigger a compl */
+
+ struct bnxt *bp;
+ int index;
+ int tx_wake_thresh;
+ struct bnxt_tx_ring_info *tx_ring;
+
+ unsigned int cp_nr_rings;
+ struct bnxt_cp_ring_info *cp_ring;
+ const struct rte_memzone *mz;
+};
+
+void bnxt_free_txq_stats(struct bnxt_tx_queue *txq);
+void bnxt_free_tx_mbufs(struct bnxt *bp);
+void bnxt_tx_queue_release_op(void *tx_queue);
+int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
+ uint16_t queue_idx,
+ uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf);
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_txr.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_txr.c
new file mode 100644
index 00000000..67bb35e0
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_txr.c
@@ -0,0 +1,442 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+
+#include <rte_byteorder.h>
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_ring.h"
+#include "bnxt_txq.h"
+#include "bnxt_txr.h"
+#include "hsi_struct_def_dpdk.h"
+#include <stdbool.h>
+
+/*
+ * TX Ring handling
+ */
+
+void bnxt_free_tx_rings(struct bnxt *bp)
+{
+ int i;
+
+ for (i = 0; i < (int)bp->tx_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+
+ if (!txq)
+ continue;
+
+ bnxt_free_ring(txq->tx_ring->tx_ring_struct);
+ rte_free(txq->tx_ring->tx_ring_struct);
+ rte_free(txq->tx_ring);
+
+ bnxt_free_ring(txq->cp_ring->cp_ring_struct);
+ rte_free(txq->cp_ring->cp_ring_struct);
+ rte_free(txq->cp_ring);
+
+ rte_free(txq);
+ bp->tx_queues[i] = NULL;
+ }
+}
+
+int bnxt_init_one_tx_ring(struct bnxt_tx_queue *txq)
+{
+ struct bnxt_tx_ring_info *txr = txq->tx_ring;
+ struct bnxt_ring *ring = txr->tx_ring_struct;
+
+ txq->tx_wake_thresh = ring->ring_size / 2;
+ ring->fw_ring_id = INVALID_HW_RING_ID;
+
+ return 0;
+}
+
+int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id)
+{
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_tx_ring_info *txr;
+ struct bnxt_ring *ring;
+
+ txr = rte_zmalloc_socket("bnxt_tx_ring",
+ sizeof(struct bnxt_tx_ring_info),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (txr == NULL)
+ return -ENOMEM;
+ txq->tx_ring = txr;
+
+ ring = rte_zmalloc_socket("bnxt_tx_ring_struct",
+ sizeof(struct bnxt_ring),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (ring == NULL)
+ return -ENOMEM;
+ txr->tx_ring_struct = ring;
+ ring->ring_size = rte_align32pow2(txq->nb_tx_desc);
+ ring->ring_mask = ring->ring_size - 1;
+ ring->bd = (void *)txr->tx_desc_ring;
+ ring->bd_dma = txr->tx_desc_mapping;
+ ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_tx_bd);
+ ring->vmem = (void **)&txr->tx_buf_ring;
+
+ cpr = rte_zmalloc_socket("bnxt_tx_ring",
+ sizeof(struct bnxt_cp_ring_info),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (cpr == NULL)
+ return -ENOMEM;
+ txq->cp_ring = cpr;
+
+ ring = rte_zmalloc_socket("bnxt_tx_ring_struct",
+ sizeof(struct bnxt_ring),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (ring == NULL)
+ return -ENOMEM;
+ cpr->cp_ring_struct = ring;
+ ring->ring_size = txr->tx_ring_struct->ring_size;
+ ring->ring_mask = ring->ring_size - 1;
+ ring->bd = (void *)cpr->cp_desc_ring;
+ ring->bd_dma = cpr->cp_desc_mapping;
+ ring->vmem_size = 0;
+ ring->vmem = NULL;
+
+ return 0;
+}
+
+static inline uint32_t bnxt_tx_avail(struct bnxt_tx_ring_info *txr)
+{
+ /* Tell compiler to fetch tx indices from memory. */
+ rte_compiler_barrier();
+
+ return txr->tx_ring_struct->ring_size -
+ ((txr->tx_prod - txr->tx_cons) &
+ txr->tx_ring_struct->ring_mask) - 1;
+}
+
+static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
+ struct bnxt_tx_queue *txq,
+ uint16_t *coal_pkts,
+ uint16_t *cmpl_next)
+{
+ struct bnxt_tx_ring_info *txr = txq->tx_ring;
+ struct tx_bd_long *txbd;
+ struct tx_bd_long_hi *txbd1;
+ uint32_t vlan_tag_flags, cfa_action;
+ bool long_bd = false;
+ uint16_t last_prod = 0;
+ struct rte_mbuf *m_seg;
+ struct bnxt_sw_tx_bd *tx_buf;
+ static const uint32_t lhint_arr[4] = {
+ TX_BD_LONG_FLAGS_LHINT_LT512,
+ TX_BD_LONG_FLAGS_LHINT_LT1K,
+ TX_BD_LONG_FLAGS_LHINT_LT2K,
+ TX_BD_LONG_FLAGS_LHINT_LT2K
+ };
+
+ if (tx_pkt->ol_flags & (PKT_TX_TCP_SEG | PKT_TX_TCP_CKSUM |
+ PKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM |
+ PKT_TX_VLAN_PKT | PKT_TX_OUTER_IP_CKSUM |
+ PKT_TX_TUNNEL_GRE | PKT_TX_TUNNEL_VXLAN |
+ PKT_TX_TUNNEL_GENEVE))
+ long_bd = true;
+
+ tx_buf = &txr->tx_buf_ring[txr->tx_prod];
+ tx_buf->mbuf = tx_pkt;
+ tx_buf->nr_bds = long_bd + tx_pkt->nb_segs;
+ last_prod = (txr->tx_prod + tx_buf->nr_bds - 1) &
+ txr->tx_ring_struct->ring_mask;
+
+ if (unlikely(bnxt_tx_avail(txr) < tx_buf->nr_bds))
+ return -ENOMEM;
+
+ txbd = &txr->tx_desc_ring[txr->tx_prod];
+ txbd->opaque = *coal_pkts;
+ txbd->flags_type = tx_buf->nr_bds << TX_BD_LONG_FLAGS_BD_CNT_SFT;
+ txbd->flags_type |= TX_BD_SHORT_FLAGS_COAL_NOW;
+ if (!*cmpl_next) {
+ txbd->flags_type |= TX_BD_LONG_FLAGS_NO_CMPL;
+ } else {
+ *coal_pkts = 0;
+ *cmpl_next = false;
+ }
+ txbd->len = tx_pkt->data_len;
+ if (tx_pkt->pkt_len >= 2014)
+ txbd->flags_type |= TX_BD_LONG_FLAGS_LHINT_GTE2K;
+ else
+ txbd->flags_type |= lhint_arr[tx_pkt->pkt_len >> 9];
+ txbd->address = rte_cpu_to_le_64(rte_mbuf_data_iova(tx_buf->mbuf));
+
+ if (long_bd) {
+ txbd->flags_type |= TX_BD_LONG_TYPE_TX_BD_LONG;
+ vlan_tag_flags = 0;
+ cfa_action = 0;
+ if (tx_buf->mbuf->ol_flags & PKT_TX_VLAN_PKT) {
+ /* shurd: Should this mask at
+ * TX_BD_LONG_CFA_META_VLAN_VID_MASK?
+ */
+ vlan_tag_flags = TX_BD_LONG_CFA_META_KEY_VLAN_TAG |
+ tx_buf->mbuf->vlan_tci;
+ /* Currently supports 8021Q, 8021AD vlan offloads
+ * QINQ1, QINQ2, QINQ3 vlan headers are deprecated
+ */
+ /* DPDK only supports 802.11q VLAN packets */
+ vlan_tag_flags |=
+ TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100;
+ }
+
+ txr->tx_prod = RING_NEXT(txr->tx_ring_struct, txr->tx_prod);
+
+ txbd1 = (struct tx_bd_long_hi *)
+ &txr->tx_desc_ring[txr->tx_prod];
+ txbd1->lflags = 0;
+ txbd1->cfa_meta = vlan_tag_flags;
+ txbd1->cfa_action = cfa_action;
+
+ if (tx_pkt->ol_flags & PKT_TX_TCP_SEG) {
+ /* TSO */
+ txbd1->lflags |= TX_BD_LONG_LFLAGS_LSO;
+ txbd1->hdr_size = tx_pkt->l2_len + tx_pkt->l3_len +
+ tx_pkt->l4_len + tx_pkt->outer_l2_len +
+ tx_pkt->outer_l3_len;
+ txbd1->mss = tx_pkt->tso_segsz;
+
+ } else if ((tx_pkt->ol_flags & PKT_TX_OIP_IIP_TCP_UDP_CKSUM) ==
+ PKT_TX_OIP_IIP_TCP_UDP_CKSUM) {
+ /* Outer IP, Inner IP, Inner TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_FLG_TIP_IP_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_OIP_IIP_TCP_CKSUM) ==
+ PKT_TX_OIP_IIP_TCP_CKSUM) {
+ /* Outer IP, Inner IP, Inner TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_FLG_TIP_IP_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_OIP_IIP_UDP_CKSUM) ==
+ PKT_TX_OIP_IIP_UDP_CKSUM) {
+ /* Outer IP, Inner IP, Inner TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_FLG_TIP_IP_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_IIP_TCP_UDP_CKSUM) ==
+ PKT_TX_IIP_TCP_UDP_CKSUM) {
+ /* (Inner) IP, (Inner) TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_FLG_IP_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_IIP_UDP_CKSUM) ==
+ PKT_TX_IIP_UDP_CKSUM) {
+ /* (Inner) IP, (Inner) TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_FLG_IP_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_IIP_TCP_CKSUM) ==
+ PKT_TX_IIP_TCP_CKSUM) {
+ /* (Inner) IP, (Inner) TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_FLG_IP_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_OIP_TCP_UDP_CKSUM) ==
+ PKT_TX_OIP_TCP_UDP_CKSUM) {
+ /* Outer IP, (Inner) TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_FLG_TIP_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_OIP_UDP_CKSUM) ==
+ PKT_TX_OIP_UDP_CKSUM) {
+ /* Outer IP, (Inner) TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_FLG_TIP_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_OIP_TCP_CKSUM) ==
+ PKT_TX_OIP_TCP_CKSUM) {
+ /* Outer IP, (Inner) TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_FLG_TIP_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_OIP_IIP_CKSUM) ==
+ PKT_TX_OIP_IIP_CKSUM) {
+ /* Outer IP, Inner IP CSO */
+ txbd1->lflags |= TX_BD_FLG_TIP_IP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_TCP_UDP_CKSUM) ==
+ PKT_TX_TCP_UDP_CKSUM) {
+ /* TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_TCP_CKSUM) ==
+ PKT_TX_TCP_CKSUM) {
+ /* TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_UDP_CKSUM) ==
+ PKT_TX_UDP_CKSUM) {
+ /* TCP/UDP CSO */
+ txbd1->lflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_IP_CKSUM) ==
+ PKT_TX_IP_CKSUM) {
+ /* IP CSO */
+ txbd1->lflags |= TX_BD_LONG_LFLAGS_IP_CHKSUM;
+ txbd1->mss = 0;
+ } else if ((tx_pkt->ol_flags & PKT_TX_OUTER_IP_CKSUM) ==
+ PKT_TX_OUTER_IP_CKSUM) {
+ /* IP CSO */
+ txbd1->lflags |= TX_BD_LONG_LFLAGS_T_IP_CHKSUM;
+ txbd1->mss = 0;
+ }
+ } else {
+ txbd->flags_type |= TX_BD_SHORT_TYPE_TX_BD_SHORT;
+ }
+
+ m_seg = tx_pkt->next;
+ /* i is set at the end of the if(long_bd) block */
+ while (txr->tx_prod != last_prod) {
+ txr->tx_prod = RING_NEXT(txr->tx_ring_struct, txr->tx_prod);
+ tx_buf = &txr->tx_buf_ring[txr->tx_prod];
+
+ txbd = &txr->tx_desc_ring[txr->tx_prod];
+ txbd->address = rte_cpu_to_le_64(rte_mbuf_data_iova(m_seg));
+ txbd->flags_type |= TX_BD_SHORT_TYPE_TX_BD_SHORT;
+ txbd->len = m_seg->data_len;
+
+ m_seg = m_seg->next;
+ }
+
+ txbd->flags_type |= TX_BD_LONG_FLAGS_PACKET_END;
+ txbd1->lflags = rte_cpu_to_le_32(txbd1->lflags);
+
+ txr->tx_prod = RING_NEXT(txr->tx_ring_struct, txr->tx_prod);
+
+ return 0;
+}
+
+static void bnxt_tx_cmp(struct bnxt_tx_queue *txq, int nr_pkts)
+{
+ struct bnxt_tx_ring_info *txr = txq->tx_ring;
+ uint16_t cons = txr->tx_cons;
+ int i, j;
+
+ for (i = 0; i < nr_pkts; i++) {
+ struct bnxt_sw_tx_bd *tx_buf;
+ struct rte_mbuf *mbuf;
+
+ tx_buf = &txr->tx_buf_ring[cons];
+ cons = RING_NEXT(txr->tx_ring_struct, cons);
+ mbuf = tx_buf->mbuf;
+ tx_buf->mbuf = NULL;
+
+ /* EW - no need to unmap DMA memory? */
+
+ for (j = 1; j < tx_buf->nr_bds; j++)
+ cons = RING_NEXT(txr->tx_ring_struct, cons);
+ rte_pktmbuf_free(mbuf);
+ }
+
+ txr->tx_cons = cons;
+}
+
+static int bnxt_handle_tx_cp(struct bnxt_tx_queue *txq)
+{
+ struct bnxt_cp_ring_info *cpr = txq->cp_ring;
+ uint32_t raw_cons = cpr->cp_raw_cons;
+ uint32_t cons;
+ uint32_t nb_tx_pkts = 0;
+ struct tx_cmpl *txcmp;
+ struct cmpl_base *cp_desc_ring = cpr->cp_desc_ring;
+ struct bnxt_ring *cp_ring_struct = cpr->cp_ring_struct;
+ uint32_t ring_mask = cp_ring_struct->ring_mask;
+ uint32_t opaque = 0;
+
+ if (((txq->tx_ring->tx_prod - txq->tx_ring->tx_cons) &
+ txq->tx_ring->tx_ring_struct->ring_mask) < txq->tx_free_thresh)
+ return 0;
+
+ do {
+ cons = RING_CMPL(ring_mask, raw_cons);
+ txcmp = (struct tx_cmpl *)&cpr->cp_desc_ring[cons];
+ rte_prefetch_non_temporal(&cp_desc_ring[(cons + 2) &
+ ring_mask]);
+
+ if (!CMPL_VALID(txcmp, cpr->valid))
+ break;
+ opaque = rte_cpu_to_le_32(txcmp->opaque);
+ NEXT_CMPL(cpr, cons, cpr->valid, 1);
+ rte_prefetch0(&cp_desc_ring[cons]);
+
+ if (CMP_TYPE(txcmp) == TX_CMPL_TYPE_TX_L2)
+ nb_tx_pkts += opaque;
+ else
+ RTE_LOG_DP(ERR, PMD,
+ "Unhandled CMP type %02x\n",
+ CMP_TYPE(txcmp));
+ raw_cons = cons;
+ } while (nb_tx_pkts < ring_mask);
+
+ if (nb_tx_pkts) {
+ bnxt_tx_cmp(txq, nb_tx_pkts);
+ cpr->cp_raw_cons = raw_cons;
+ B_CP_DB(cpr, cpr->cp_raw_cons, ring_mask);
+ }
+
+ return nb_tx_pkts;
+}
+
+uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ struct bnxt_tx_queue *txq = tx_queue;
+ uint16_t nb_tx_pkts = 0;
+ uint16_t coal_pkts = 0;
+ uint16_t cmpl_next = txq->cmpl_next;
+
+ /* Handle TX completions */
+ bnxt_handle_tx_cp(txq);
+
+ /* Tx queue was stopped; wait for it to be restarted */
+ if (txq->tx_deferred_start) {
+ PMD_DRV_LOG(DEBUG, "Tx q stopped;return\n");
+ return 0;
+ }
+
+ txq->cmpl_next = 0;
+ /* Handle TX burst request */
+ for (nb_tx_pkts = 0; nb_tx_pkts < nb_pkts; nb_tx_pkts++) {
+ int rc;
+
+ /* Request a completion on first and last packet */
+ cmpl_next |= (nb_pkts == nb_tx_pkts + 1);
+ coal_pkts++;
+ rc = bnxt_start_xmit(tx_pkts[nb_tx_pkts], txq,
+ &coal_pkts, &cmpl_next);
+
+ if (unlikely(rc)) {
+ /* Request a completion in next cycle */
+ txq->cmpl_next = 1;
+ break;
+ }
+ }
+
+ if (nb_tx_pkts)
+ B_TX_DB(txq->tx_ring->tx_doorbell, txq->tx_ring->tx_prod);
+
+ return nb_tx_pkts;
+}
+
+int bnxt_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_tx_queue *txq = bp->tx_queues[tx_queue_id];
+
+ dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
+ txq->tx_deferred_start = false;
+ PMD_DRV_LOG(DEBUG, "Tx queue started\n");
+
+ return 0;
+}
+
+int bnxt_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct bnxt_tx_queue *txq = bp->tx_queues[tx_queue_id];
+
+ /* Handle TX completions */
+ bnxt_handle_tx_cp(txq);
+
+ dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+ txq->tx_deferred_start = true;
+ PMD_DRV_LOG(DEBUG, "Tx queue stopped\n");
+
+ return 0;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_txr.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_txr.h
new file mode 100644
index 00000000..7f3c7cdb
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_txr.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_TXR_H_
+#define _BNXT_TXR_H_
+
+#include <rte_io.h>
+
+#define MAX_TX_RINGS 16
+#define BNXT_TX_PUSH_THRESH 92
+
+#define B_TX_DB(db, prod) rte_write32((DB_KEY_TX | (prod)), db)
+
+struct bnxt_tx_ring_info {
+ uint16_t tx_prod;
+ uint16_t tx_cons;
+ void *tx_doorbell;
+
+ struct tx_bd_long *tx_desc_ring;
+ struct bnxt_sw_tx_bd *tx_buf_ring;
+
+ rte_iova_t tx_desc_mapping;
+
+#define BNXT_DEV_STATE_CLOSING 0x1
+ uint32_t dev_state;
+
+ struct bnxt_ring *tx_ring_struct;
+};
+
+struct bnxt_sw_tx_bd {
+ struct rte_mbuf *mbuf; /* mbuf associated with TX descriptor */
+ uint8_t is_gso;
+ unsigned short nr_bds;
+};
+
+void bnxt_free_tx_rings(struct bnxt *bp);
+int bnxt_init_one_tx_ring(struct bnxt_tx_queue *txq);
+int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id);
+uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+int bnxt_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+int bnxt_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+
+#define PKT_TX_OIP_IIP_TCP_UDP_CKSUM (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \
+ PKT_TX_IP_CKSUM | PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_OIP_IIP_UDP_CKSUM (PKT_TX_UDP_CKSUM | \
+ PKT_TX_IP_CKSUM | PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_OIP_IIP_TCP_CKSUM (PKT_TX_TCP_CKSUM | \
+ PKT_TX_IP_CKSUM | PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_IIP_TCP_UDP_CKSUM (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \
+ PKT_TX_IP_CKSUM)
+#define PKT_TX_IIP_TCP_CKSUM (PKT_TX_TCP_CKSUM | PKT_TX_IP_CKSUM)
+#define PKT_TX_IIP_UDP_CKSUM (PKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM)
+#define PKT_TX_OIP_TCP_UDP_CKSUM (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \
+ PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_OIP_UDP_CKSUM (PKT_TX_UDP_CKSUM | \
+ PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_OIP_TCP_CKSUM (PKT_TX_TCP_CKSUM | \
+ PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_OIP_IIP_CKSUM (PKT_TX_IP_CKSUM | \
+ PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_TCP_UDP_CKSUM (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)
+
+
+#define TX_BD_FLG_TIP_IP_TCP_UDP_CHKSUM (TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM | \
+ TX_BD_LONG_LFLAGS_T_IP_CHKSUM | \
+ TX_BD_LONG_LFLAGS_IP_CHKSUM)
+#define TX_BD_FLG_IP_TCP_UDP_CHKSUM (TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM | \
+ TX_BD_LONG_LFLAGS_IP_CHKSUM)
+#define TX_BD_FLG_TIP_IP_CHKSUM (TX_BD_LONG_LFLAGS_T_IP_CHKSUM | \
+ TX_BD_LONG_LFLAGS_IP_CHKSUM)
+#define TX_BD_FLG_TIP_TCP_UDP_CHKSUM (TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM | \
+ TX_BD_LONG_LFLAGS_T_IP_CHKSUM)
+
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_util.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_util.c
new file mode 100644
index 00000000..7d334271
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_util.c
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+
+#include "bnxt_util.h"
+
+int bnxt_check_zero_bytes(const uint8_t *bytes, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (bytes[i] != 0x00)
+ return 0;
+ return 1;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_util.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_util.h
new file mode 100644
index 00000000..2378833c
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_util.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_UTIL_H_
+#define _BNXT_UTIL_H_
+
+int bnxt_check_zero_bytes(const uint8_t *bytes, int len);
+
+#endif /* _BNXT_UTIL_H_ */
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_vnic.c b/src/spdk/dpdk/drivers/net/bnxt/bnxt_vnic.c
new file mode 100644
index 00000000..c0577cd7
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_vnic.c
@@ -0,0 +1,240 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+
+#include <rte_memzone.h>
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_vnic.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * VNIC Functions
+ */
+
+static void prandom_bytes(void *dest_ptr, size_t len)
+{
+ char *dest = (char *)dest_ptr;
+ uint64_t rb;
+
+ while (len) {
+ rb = rte_rand();
+ if (len >= 8) {
+ memcpy(dest, &rb, 8);
+ len -= 8;
+ dest += 8;
+ } else {
+ memcpy(dest, &rb, len);
+ dest += len;
+ len = 0;
+ }
+ }
+}
+
+void bnxt_init_vnics(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+ uint16_t max_vnics;
+ int i;
+
+ max_vnics = bp->max_vnics;
+ STAILQ_INIT(&bp->free_vnic_list);
+ for (i = 0; i < max_vnics; i++) {
+ vnic = &bp->vnic_info[i];
+ vnic->fw_vnic_id = (uint16_t)HWRM_NA_SIGNATURE;
+ vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
+ vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
+ vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
+ vnic->hash_mode =
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;
+
+ prandom_bytes(vnic->rss_hash_key, HW_HASH_KEY_SIZE);
+ STAILQ_INIT(&vnic->filter);
+ STAILQ_INIT(&vnic->flow_list);
+ STAILQ_INSERT_TAIL(&bp->free_vnic_list, vnic, next);
+ }
+ for (i = 0; i < MAX_FF_POOLS; i++)
+ STAILQ_INIT(&bp->ff_pool[i]);
+}
+
+int bnxt_free_vnic(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+ int pool)
+{
+ struct bnxt_vnic_info *temp;
+
+ temp = STAILQ_FIRST(&bp->ff_pool[pool]);
+ while (temp) {
+ if (temp == vnic) {
+ STAILQ_REMOVE(&bp->ff_pool[pool], vnic,
+ bnxt_vnic_info, next);
+ vnic->fw_vnic_id = (uint16_t)HWRM_NA_SIGNATURE;
+ STAILQ_INSERT_TAIL(&bp->free_vnic_list, vnic,
+ next);
+ return 0;
+ }
+ temp = STAILQ_NEXT(temp, next);
+ }
+ PMD_DRV_LOG(ERR, "VNIC %p is not found in pool[%d]\n", vnic, pool);
+ return -EINVAL;
+}
+
+struct bnxt_vnic_info *bnxt_alloc_vnic(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+
+ /* Find the 1st unused vnic from the free_vnic_list pool*/
+ vnic = STAILQ_FIRST(&bp->free_vnic_list);
+ if (!vnic) {
+ PMD_DRV_LOG(ERR, "No more free VNIC resources\n");
+ return NULL;
+ }
+ STAILQ_REMOVE_HEAD(&bp->free_vnic_list, next);
+ return vnic;
+}
+
+void bnxt_free_all_vnics(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *temp, *next;
+ int i;
+
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ temp = STAILQ_FIRST(&bp->ff_pool[i]);
+ while (temp) {
+ next = STAILQ_NEXT(temp, next);
+ STAILQ_REMOVE(&bp->ff_pool[i], temp, bnxt_vnic_info,
+ next);
+ STAILQ_INSERT_TAIL(&bp->free_vnic_list, temp, next);
+ temp = next;
+ }
+ }
+}
+
+void bnxt_free_vnic_attributes(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+
+ STAILQ_FOREACH(vnic, &bp->free_vnic_list, next) {
+ if (vnic->rss_table) {
+ /* 'Unreserve' the rss_table */
+ /* N/A */
+
+ vnic->rss_table = NULL;
+ }
+
+ if (vnic->rss_hash_key) {
+ /* 'Unreserve' the rss_hash_key */
+ /* N/A */
+
+ vnic->rss_hash_key = NULL;
+ }
+ }
+}
+
+int bnxt_alloc_vnic_attributes(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+ struct rte_pci_device *pdev = bp->pdev;
+ const struct rte_memzone *mz;
+ char mz_name[RTE_MEMZONE_NAMESIZE];
+ uint32_t entry_length = RTE_CACHE_LINE_ROUNDUP(
+ HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table) +
+ HW_HASH_KEY_SIZE +
+ BNXT_MAX_MC_ADDRS * ETHER_ADDR_LEN);
+ uint16_t max_vnics;
+ int i;
+ rte_iova_t mz_phys_addr;
+
+ max_vnics = bp->max_vnics;
+ snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+ "bnxt_%04x:%02x:%02x:%02x_vnicattr", pdev->addr.domain,
+ pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
+ mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+ mz = rte_memzone_lookup(mz_name);
+ if (!mz) {
+ mz = rte_memzone_reserve(mz_name,
+ entry_length * max_vnics, SOCKET_ID_ANY,
+ RTE_MEMZONE_2MB |
+ RTE_MEMZONE_SIZE_HINT_ONLY |
+ RTE_MEMZONE_IOVA_CONTIG);
+ if (!mz)
+ return -ENOMEM;
+ }
+ mz_phys_addr = mz->iova;
+ if ((unsigned long)mz->addr == mz_phys_addr) {
+ PMD_DRV_LOG(WARNING,
+ "Memzone physical address same as virtual.\n");
+ PMD_DRV_LOG(WARNING,
+ "Using rte_mem_virt2iova()\n");
+ mz_phys_addr = rte_mem_virt2iova(mz->addr);
+ if (mz_phys_addr == 0) {
+ PMD_DRV_LOG(ERR,
+ "unable to map vnic address to physical memory\n");
+ return -ENOMEM;
+ }
+ }
+
+ for (i = 0; i < max_vnics; i++) {
+ vnic = &bp->vnic_info[i];
+
+ /* Allocate rss table and hash key */
+ vnic->rss_table =
+ (void *)((char *)mz->addr + (entry_length * i));
+ memset(vnic->rss_table, -1, entry_length);
+
+ vnic->rss_table_dma_addr = mz_phys_addr + (entry_length * i);
+ vnic->rss_hash_key = (void *)((char *)vnic->rss_table +
+ HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table));
+
+ vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr +
+ HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table);
+ vnic->mc_list = (void *)((char *)vnic->rss_hash_key +
+ HW_HASH_KEY_SIZE);
+ vnic->mc_list_dma_addr = vnic->rss_hash_key_dma_addr +
+ HW_HASH_KEY_SIZE;
+ }
+
+ return 0;
+}
+
+void bnxt_free_vnic_mem(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+ uint16_t max_vnics, i;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ max_vnics = bp->max_vnics;
+ for (i = 0; i < max_vnics; i++) {
+ vnic = &bp->vnic_info[i];
+ if (vnic->fw_vnic_id != (uint16_t)HWRM_NA_SIGNATURE) {
+ PMD_DRV_LOG(ERR, "VNIC is not freed yet!\n");
+ /* TODO Call HWRM to free VNIC */
+ }
+ }
+
+ rte_free(bp->vnic_info);
+ bp->vnic_info = NULL;
+}
+
+int bnxt_alloc_vnic_mem(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic_mem;
+ uint16_t max_vnics;
+
+ max_vnics = bp->max_vnics;
+ /* Allocate memory for VNIC pool and filter pool */
+ vnic_mem = rte_zmalloc("bnxt_vnic_info",
+ max_vnics * sizeof(struct bnxt_vnic_info), 0);
+ if (vnic_mem == NULL) {
+ PMD_DRV_LOG(ERR, "Failed to alloc memory for %d VNICs",
+ max_vnics);
+ return -ENOMEM;
+ }
+ bp->vnic_info = vnic_mem;
+ return 0;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/bnxt_vnic.h b/src/spdk/dpdk/drivers/net/bnxt/bnxt_vnic.h
new file mode 100644
index 00000000..9029f78c
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/bnxt_vnic.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _BNXT_VNIC_H_
+#define _BNXT_VNIC_H_
+
+#include <sys/queue.h>
+#include <stdbool.h>
+
+struct bnxt_vnic_info {
+ STAILQ_ENTRY(bnxt_vnic_info) next;
+ uint8_t ff_pool_idx;
+
+ uint16_t fw_vnic_id; /* returned by Chimp during alloc */
+ uint16_t rss_rule;
+ uint16_t start_grp_id;
+ uint16_t end_grp_id;
+ uint16_t *fw_grp_ids;
+ uint16_t dflt_ring_grp;
+ uint16_t mru;
+ uint16_t hash_type;
+ uint8_t hash_mode;
+ rte_iova_t rss_table_dma_addr;
+ uint16_t *rss_table;
+ rte_iova_t rss_hash_key_dma_addr;
+ void *rss_hash_key;
+ rte_iova_t mc_list_dma_addr;
+ char *mc_list;
+ uint32_t mc_addr_cnt;
+#define BNXT_MAX_MC_ADDRS 16
+ uint32_t flags;
+#define BNXT_VNIC_INFO_PROMISC (1 << 0)
+#define BNXT_VNIC_INFO_ALLMULTI (1 << 1)
+#define BNXT_VNIC_INFO_BCAST (1 << 2)
+#define BNXT_VNIC_INFO_UCAST (1 << 3)
+#define BNXT_VNIC_INFO_MCAST (1 << 4)
+#define BNXT_VNIC_INFO_TAGGED (1 << 5)
+#define BNXT_VNIC_INFO_UNTAGGED (1 << 6)
+
+ uint16_t cos_rule;
+ uint16_t lb_rule;
+ bool vlan_strip;
+ bool func_default;
+ bool bd_stall;
+ bool roce_dual;
+ bool roce_only;
+ bool rss_dflt_cr;
+
+ STAILQ_HEAD(, bnxt_filter_info) filter;
+ STAILQ_HEAD(, rte_flow) flow_list;
+};
+
+struct bnxt;
+void bnxt_init_vnics(struct bnxt *bp);
+int bnxt_free_vnic(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+ int pool);
+struct bnxt_vnic_info *bnxt_alloc_vnic(struct bnxt *bp);
+void bnxt_free_all_vnics(struct bnxt *bp);
+void bnxt_free_vnic_attributes(struct bnxt *bp);
+int bnxt_alloc_vnic_attributes(struct bnxt *bp);
+void bnxt_free_vnic_mem(struct bnxt *bp);
+int bnxt_alloc_vnic_mem(struct bnxt *bp);
+#endif
diff --git a/src/spdk/dpdk/drivers/net/bnxt/hsi_struct_def_dpdk.h b/src/spdk/dpdk/drivers/net/bnxt/hsi_struct_def_dpdk.h
new file mode 100644
index 00000000..f5c7b422
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -0,0 +1,28211 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2014-2018 Broadcom Limited
+ * All rights reserved.
+ *
+ * DO NOT MODIFY!!! This file is automatically generated.
+ */
+
+#ifndef _HSI_STRUCT_DEF_DPDK_H_
+#define _HSI_STRUCT_DEF_DPDK_H_
+
+/* This is the HWRM command header. */
+/* hwrm_cmd_hdr (size:128b/16B) */
+struct hwrm_cmd_hdr {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+/* This is the HWRM response header. */
+/* hwrm_resp_hdr (size:64b/8B) */
+struct hwrm_resp_hdr {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+} __attribute__((packed));
+
+/*
+ * TLV encapsulated message. Use the TLV type field of the
+ * TLV to determine the type of message encapsulated.
+ */
+#define CMD_DISCR_TLV_ENCAP UINT32_C(0x8000)
+#define CMD_DISCR_LAST CMD_DISCR_TLV_ENCAP
+
+
+/* HWRM request message */
+#define TLV_TYPE_HWRM_REQUEST UINT32_C(0x1)
+/* HWRM response message */
+#define TLV_TYPE_HWRM_RESPONSE UINT32_C(0x2)
+/* RoCE slow path command */
+#define TLV_TYPE_ROCE_SP_COMMAND UINT32_C(0x3)
+/* Engine CKV - The device's serial number. */
+#define TLV_TYPE_ENGINE_CKV_DEVICE_SERIAL_NUMBER UINT32_C(0x8001)
+/* Engine CKV - Per-function random nonce data. */
+#define TLV_TYPE_ENGINE_CKV_NONCE UINT32_C(0x8002)
+/* Engine CKV - Initialization vector. */
+#define TLV_TYPE_ENGINE_CKV_IV UINT32_C(0x8003)
+/* Engine CKV - Authentication tag. */
+#define TLV_TYPE_ENGINE_CKV_AUTH_TAG UINT32_C(0x8004)
+/* Engine CKV - The encrypted data. */
+#define TLV_TYPE_ENGINE_CKV_CIPHERTEXT UINT32_C(0x8005)
+/* Engine CKV - Supported algorithms. */
+#define TLV_TYPE_ENGINE_CKV_ALGORITHMS UINT32_C(0x8006)
+/* Engine CKV - The EC curve name and ECC public key information. */
+#define TLV_TYPE_ENGINE_CKV_ECC_PUBLIC_KEY UINT32_C(0x8007)
+/* Engine CKV - The ECDSA signature. */
+#define TLV_TYPE_ENGINE_CKV_ECDSA_SIGNATURE UINT32_C(0x8008)
+#define TLV_TYPE_LAST \
+ TLV_TYPE_ENGINE_CKV_ECDSA_SIGNATURE
+
+
+/* tlv (size:64b/8B) */
+struct tlv {
+ /*
+ * The command discriminator is used to differentiate between various
+ * types of HWRM messages. This includes legacy HWRM and RoCE slowpath
+ * command messages as well as newer TLV encapsulated HWRM commands.
+ *
+ * For TLV encapsulated messages this field must be 0x8000.
+ */
+ uint16_t cmd_discr;
+ uint8_t reserved_8b;
+ uint8_t flags;
+ /*
+ * Indicates the presence of additional TLV encapsulated data
+ * follows this TLV.
+ */
+ #define TLV_FLAGS_MORE UINT32_C(0x1)
+ /* Last TLV in a sequence of TLVs. */
+ #define TLV_FLAGS_MORE_LAST UINT32_C(0x0)
+ /* More TLVs follow this TLV. */
+ #define TLV_FLAGS_MORE_NOT_LAST UINT32_C(0x1)
+ /*
+ * When an HWRM receiver detects a TLV type that it does not
+ * support with the TLV required flag set, the receiver must
+ * reject the HWRM message with an error code indicating an
+ * unsupported TLV type.
+ */
+ #define TLV_FLAGS_REQUIRED UINT32_C(0x2)
+ /* No */
+ #define TLV_FLAGS_REQUIRED_NO (UINT32_C(0x0) << 1)
+ /* Yes */
+ #define TLV_FLAGS_REQUIRED_YES (UINT32_C(0x1) << 1)
+ #define TLV_FLAGS_REQUIRED_LAST TLV_FLAGS_REQUIRED_YES
+ /*
+ * This field defines the TLV type value which is divided into
+ * two ranges to differentiate between global and local TLV types.
+ * Global TLV types must be unique across all defined TLV types.
+ * Local TLV types are valid only for extensions to a given
+ * HWRM message and may be repeated across different HWRM message
+ * types. There is a direct correlation of each HWRM message type
+ * to a single global TLV type value.
+ *
+ * Global TLV range: `0 - (63k-1)`
+ *
+ * Local TLV range: `63k - (64k-1)`
+ */
+ uint16_t tlv_type;
+ /*
+ * Length of the message data encapsulated by this TLV in bytes.
+ * This length does not include the size of the TLV header itself
+ * and it must be an integer multiple of 8B.
+ */
+ uint16_t length;
+} __attribute__((packed));
+
+/* Input */
+/* input (size:128b/16B) */
+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 */
+/* output (size:64b/8B) */
+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));
+
+/* Short Command Structure */
+/* hwrm_short_input (size:128b/16B) */
+struct hwrm_short_input {
+ /*
+ * This field indicates the type of request in the request buffer.
+ * The format for the rest of the command (request) is determined
+ * by this field.
+ */
+ uint16_t req_type;
+ /*
+ * This field indicates a signature that is used to identify short
+ * form of the command listed here. This field shall be set to
+ * 17185 (0x4321).
+ */
+ uint16_t signature;
+ /* Signature indicating this is a short form of HWRM command */
+ #define HWRM_SHORT_INPUT_SIGNATURE_SHORT_CMD UINT32_C(0x4321)
+ #define HWRM_SHORT_INPUT_SIGNATURE_LAST \
+ HWRM_SHORT_INPUT_SIGNATURE_SHORT_CMD
+ /* Reserved for future use. */
+ uint16_t unused_0;
+ /* This value indicates the length of the request. */
+ uint16_t size;
+ /*
+ * This is the host address where the request was written.
+ * This area must be 16B aligned.
+ */
+ uint64_t req_addr;
+} __attribute__((packed));
+
+/*
+ * Command numbering
+ * # NOTE - definitions already in hwrm_req_type, in hwrm_types.yaml
+ * # So only structure definition is provided here.
+ */
+/* cmd_nums (size:64b/8B) */
+struct cmd_nums {
+ /*
+ * This version of the specification defines the commands listed in
+ * the table below. The following are general implementation
+ * requirements for these commands:
+ *
+ * # All commands listed below that are marked neither
+ * reserved nor experimental shall be implemented by the HWRM.
+ * # A HWRM client compliant to this specification should not use
+ * commands outside of the list below.
+ * # A HWRM client compliant to this specification should not use
+ * command numbers marked reserved below.
+ * # A command marked experimental below may not be implemented
+ * by the HWRM.
+ * # A command marked experimental may change in the
+ * future version of the HWRM specification.
+ * # A command not listed below may be implemented by the HWRM.
+ * The behavior of commands that are not listed below is outside
+ * the scope of this specification.
+ */
+ uint16_t req_type;
+ #define HWRM_VER_GET UINT32_C(0x0)
+ #define HWRM_FUNC_BUF_UNRGTR UINT32_C(0xe)
+ #define HWRM_FUNC_VF_CFG UINT32_C(0xf)
+ /* Reserved for future use. */
+ #define HWRM_RESERVED1 UINT32_C(0x10)
+ #define HWRM_FUNC_RESET UINT32_C(0x11)
+ #define HWRM_FUNC_GETFID UINT32_C(0x12)
+ #define HWRM_FUNC_VF_ALLOC UINT32_C(0x13)
+ #define HWRM_FUNC_VF_FREE UINT32_C(0x14)
+ #define HWRM_FUNC_QCAPS UINT32_C(0x15)
+ #define HWRM_FUNC_QCFG UINT32_C(0x16)
+ #define HWRM_FUNC_CFG UINT32_C(0x17)
+ #define HWRM_FUNC_QSTATS UINT32_C(0x18)
+ #define HWRM_FUNC_CLR_STATS UINT32_C(0x19)
+ #define HWRM_FUNC_DRV_UNRGTR UINT32_C(0x1a)
+ #define HWRM_FUNC_VF_RESC_FREE UINT32_C(0x1b)
+ #define HWRM_FUNC_VF_VNIC_IDS_QUERY UINT32_C(0x1c)
+ #define HWRM_FUNC_DRV_RGTR UINT32_C(0x1d)
+ #define HWRM_FUNC_DRV_QVER UINT32_C(0x1e)
+ #define HWRM_FUNC_BUF_RGTR UINT32_C(0x1f)
+ #define HWRM_PORT_PHY_CFG UINT32_C(0x20)
+ #define HWRM_PORT_MAC_CFG UINT32_C(0x21)
+ /* Experimental */
+ #define HWRM_PORT_TS_QUERY UINT32_C(0x22)
+ #define HWRM_PORT_QSTATS UINT32_C(0x23)
+ #define HWRM_PORT_LPBK_QSTATS UINT32_C(0x24)
+ /* Experimental */
+ #define HWRM_PORT_CLR_STATS UINT32_C(0x25)
+ /* Experimental */
+ #define HWRM_PORT_LPBK_CLR_STATS UINT32_C(0x26)
+ #define HWRM_PORT_PHY_QCFG UINT32_C(0x27)
+ #define HWRM_PORT_MAC_QCFG UINT32_C(0x28)
+ /* Experimental */
+ #define HWRM_PORT_MAC_PTP_QCFG UINT32_C(0x29)
+ #define HWRM_PORT_PHY_QCAPS UINT32_C(0x2a)
+ #define HWRM_PORT_PHY_I2C_WRITE UINT32_C(0x2b)
+ #define HWRM_PORT_PHY_I2C_READ UINT32_C(0x2c)
+ #define HWRM_PORT_LED_CFG UINT32_C(0x2d)
+ #define HWRM_PORT_LED_QCFG UINT32_C(0x2e)
+ #define HWRM_PORT_LED_QCAPS UINT32_C(0x2f)
+ #define HWRM_QUEUE_QPORTCFG UINT32_C(0x30)
+ #define HWRM_QUEUE_QCFG UINT32_C(0x31)
+ #define HWRM_QUEUE_CFG UINT32_C(0x32)
+ #define HWRM_FUNC_VLAN_CFG UINT32_C(0x33)
+ #define HWRM_FUNC_VLAN_QCFG UINT32_C(0x34)
+ #define HWRM_QUEUE_PFCENABLE_QCFG UINT32_C(0x35)
+ #define HWRM_QUEUE_PFCENABLE_CFG UINT32_C(0x36)
+ #define HWRM_QUEUE_PRI2COS_QCFG UINT32_C(0x37)
+ #define HWRM_QUEUE_PRI2COS_CFG UINT32_C(0x38)
+ #define HWRM_QUEUE_COS2BW_QCFG UINT32_C(0x39)
+ #define HWRM_QUEUE_COS2BW_CFG UINT32_C(0x3a)
+ /* Experimental */
+ #define HWRM_QUEUE_DSCP_QCAPS UINT32_C(0x3b)
+ /* Experimental */
+ #define HWRM_QUEUE_DSCP2PRI_QCFG UINT32_C(0x3c)
+ /* Experimental */
+ #define HWRM_QUEUE_DSCP2PRI_CFG UINT32_C(0x3d)
+ #define HWRM_VNIC_ALLOC UINT32_C(0x40)
+ #define HWRM_VNIC_FREE UINT32_C(0x41)
+ #define HWRM_VNIC_CFG UINT32_C(0x42)
+ #define HWRM_VNIC_QCFG UINT32_C(0x43)
+ #define HWRM_VNIC_TPA_CFG UINT32_C(0x44)
+ /* Experimental */
+ #define HWRM_VNIC_TPA_QCFG UINT32_C(0x45)
+ #define HWRM_VNIC_RSS_CFG UINT32_C(0x46)
+ #define HWRM_VNIC_RSS_QCFG UINT32_C(0x47)
+ #define HWRM_VNIC_PLCMODES_CFG UINT32_C(0x48)
+ #define HWRM_VNIC_PLCMODES_QCFG UINT32_C(0x49)
+ #define HWRM_VNIC_QCAPS UINT32_C(0x4a)
+ #define HWRM_RING_ALLOC UINT32_C(0x50)
+ #define HWRM_RING_FREE UINT32_C(0x51)
+ #define HWRM_RING_CMPL_RING_QAGGINT_PARAMS UINT32_C(0x52)
+ #define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS UINT32_C(0x53)
+ #define HWRM_RING_RESET UINT32_C(0x5e)
+ #define HWRM_RING_GRP_ALLOC UINT32_C(0x60)
+ #define HWRM_RING_GRP_FREE UINT32_C(0x61)
+ /* Reserved for future use. */
+ #define HWRM_RESERVED5 UINT32_C(0x64)
+ /* Reserved for future use. */
+ #define HWRM_RESERVED6 UINT32_C(0x65)
+ #define HWRM_VNIC_RSS_COS_LB_CTX_ALLOC UINT32_C(0x70)
+ #define HWRM_VNIC_RSS_COS_LB_CTX_FREE UINT32_C(0x71)
+ #define HWRM_CFA_L2_FILTER_ALLOC UINT32_C(0x90)
+ #define HWRM_CFA_L2_FILTER_FREE UINT32_C(0x91)
+ #define HWRM_CFA_L2_FILTER_CFG UINT32_C(0x92)
+ #define HWRM_CFA_L2_SET_RX_MASK UINT32_C(0x93)
+ #define HWRM_CFA_VLAN_ANTISPOOF_CFG UINT32_C(0x94)
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC UINT32_C(0x95)
+ #define HWRM_CFA_TUNNEL_FILTER_FREE UINT32_C(0x96)
+ /* Experimental */
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC UINT32_C(0x97)
+ /* Experimental */
+ #define HWRM_CFA_ENCAP_RECORD_FREE UINT32_C(0x98)
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC UINT32_C(0x99)
+ #define HWRM_CFA_NTUPLE_FILTER_FREE UINT32_C(0x9a)
+ #define HWRM_CFA_NTUPLE_FILTER_CFG UINT32_C(0x9b)
+ /* Experimental */
+ #define HWRM_CFA_EM_FLOW_ALLOC UINT32_C(0x9c)
+ /* Experimental */
+ #define HWRM_CFA_EM_FLOW_FREE UINT32_C(0x9d)
+ /* Experimental */
+ #define HWRM_CFA_EM_FLOW_CFG UINT32_C(0x9e)
+ #define HWRM_TUNNEL_DST_PORT_QUERY UINT32_C(0xa0)
+ #define HWRM_TUNNEL_DST_PORT_ALLOC UINT32_C(0xa1)
+ #define HWRM_TUNNEL_DST_PORT_FREE UINT32_C(0xa2)
+ #define HWRM_STAT_CTX_ALLOC UINT32_C(0xb0)
+ #define HWRM_STAT_CTX_FREE UINT32_C(0xb1)
+ #define HWRM_STAT_CTX_QUERY UINT32_C(0xb2)
+ #define HWRM_STAT_CTX_CLR_STATS UINT32_C(0xb3)
+ #define HWRM_PORT_QSTATS_EXT UINT32_C(0xb4)
+ #define HWRM_FW_RESET UINT32_C(0xc0)
+ #define HWRM_FW_QSTATUS UINT32_C(0xc1)
+ /* Experimental */
+ #define HWRM_FW_SET_TIME UINT32_C(0xc8)
+ /* Experimental */
+ #define HWRM_FW_GET_TIME UINT32_C(0xc9)
+ /* Experimental */
+ #define HWRM_FW_SET_STRUCTURED_DATA UINT32_C(0xca)
+ /* Experimental */
+ #define HWRM_FW_GET_STRUCTURED_DATA UINT32_C(0xcb)
+ /* Experimental */
+ #define HWRM_FW_IPC_MAILBOX UINT32_C(0xcc)
+ #define HWRM_EXEC_FWD_RESP UINT32_C(0xd0)
+ #define HWRM_REJECT_FWD_RESP UINT32_C(0xd1)
+ #define HWRM_FWD_RESP UINT32_C(0xd2)
+ #define HWRM_FWD_ASYNC_EVENT_CMPL UINT32_C(0xd3)
+ #define HWRM_OEM_CMD UINT32_C(0xd4)
+ #define HWRM_TEMP_MONITOR_QUERY UINT32_C(0xe0)
+ #define HWRM_WOL_FILTER_ALLOC UINT32_C(0xf0)
+ #define HWRM_WOL_FILTER_FREE UINT32_C(0xf1)
+ #define HWRM_WOL_FILTER_QCFG UINT32_C(0xf2)
+ #define HWRM_WOL_REASON_QCFG UINT32_C(0xf3)
+ /* Experimental */
+ #define HWRM_CFA_METER_PROFILE_ALLOC UINT32_C(0xf5)
+ /* Experimental */
+ #define HWRM_CFA_METER_PROFILE_FREE UINT32_C(0xf6)
+ /* Experimental */
+ #define HWRM_CFA_METER_PROFILE_CFG UINT32_C(0xf7)
+ /* Experimental */
+ #define HWRM_CFA_METER_INSTANCE_ALLOC UINT32_C(0xf8)
+ /* Experimental */
+ #define HWRM_CFA_METER_INSTANCE_FREE UINT32_C(0xf9)
+ /* Experimental */
+ #define HWRM_CFA_VFR_ALLOC UINT32_C(0xfd)
+ /* Experimental */
+ #define HWRM_CFA_VFR_FREE UINT32_C(0xfe)
+ /* Experimental */
+ #define HWRM_CFA_VF_PAIR_ALLOC UINT32_C(0x100)
+ /* Experimental */
+ #define HWRM_CFA_VF_PAIR_FREE UINT32_C(0x101)
+ /* Experimental */
+ #define HWRM_CFA_VF_PAIR_INFO UINT32_C(0x102)
+ /* Experimental */
+ #define HWRM_CFA_FLOW_ALLOC UINT32_C(0x103)
+ /* Experimental */
+ #define HWRM_CFA_FLOW_FREE UINT32_C(0x104)
+ /* Experimental */
+ #define HWRM_CFA_FLOW_FLUSH UINT32_C(0x105)
+ /* Experimental */
+ #define HWRM_CFA_FLOW_STATS UINT32_C(0x106)
+ /* Experimental */
+ #define HWRM_CFA_FLOW_INFO UINT32_C(0x107)
+ /* Experimental */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC UINT32_C(0x108)
+ /* Experimental */
+ #define HWRM_CFA_DECAP_FILTER_FREE UINT32_C(0x109)
+ #define HWRM_CFA_VLAN_ANTISPOOF_QCFG UINT32_C(0x10a)
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC UINT32_C(0x10b)
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE UINT32_C(0x10c)
+ /* Experimental */
+ #define HWRM_CFA_PAIR_ALLOC UINT32_C(0x10d)
+ /* Experimental */
+ #define HWRM_CFA_PAIR_FREE UINT32_C(0x10e)
+ /* Experimental */
+ #define HWRM_CFA_PAIR_INFO UINT32_C(0x10f)
+ /* Experimental */
+ #define HWRM_FW_IPC_MSG UINT32_C(0x110)
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO UINT32_C(0x111)
+ /* Engine CKV - Ping the device and SRT firmware to get the public key. */
+ #define HWRM_ENGINE_CKV_HELLO UINT32_C(0x12d)
+ /* Engine CKV - Get the current allocation status of keys provisioned in the key vault. */
+ #define HWRM_ENGINE_CKV_STATUS UINT32_C(0x12e)
+ /* Engine CKV - Add a new CKEK used to encrypt keys. */
+ #define HWRM_ENGINE_CKV_CKEK_ADD UINT32_C(0x12f)
+ /* Engine CKV - Delete a previously added CKEK. */
+ #define HWRM_ENGINE_CKV_CKEK_DELETE UINT32_C(0x130)
+ /* Engine CKV - Add a new key to the key vault. */
+ #define HWRM_ENGINE_CKV_KEY_ADD UINT32_C(0x131)
+ /* Engine CKV - Delete a key from the key vault. */
+ #define HWRM_ENGINE_CKV_KEY_DELETE UINT32_C(0x132)
+ /* Engine CKV - Delete all keys from the key vault. */
+ #define HWRM_ENGINE_CKV_FLUSH UINT32_C(0x133)
+ /* Engine CKV - Get random data. */
+ #define HWRM_ENGINE_CKV_RNG_GET UINT32_C(0x134)
+ /* Engine CKV - Generate and encrypt a new AES key. */
+ #define HWRM_ENGINE_CKV_KEY_GEN UINT32_C(0x135)
+ /* Engine - Query the available queue groups configuration. */
+ #define HWRM_ENGINE_QG_CONFIG_QUERY UINT32_C(0x13c)
+ /* Engine - Query the queue groups assigned to a function. */
+ #define HWRM_ENGINE_QG_QUERY UINT32_C(0x13d)
+ /* Engine - Query the available queue group meter profile configuration. */
+ #define HWRM_ENGINE_QG_METER_PROFILE_CONFIG_QUERY UINT32_C(0x13e)
+ /* Engine - Query the configuration of a queue group meter profile. */
+ #define HWRM_ENGINE_QG_METER_PROFILE_QUERY UINT32_C(0x13f)
+ /* Engine - Allocate a queue group meter profile. */
+ #define HWRM_ENGINE_QG_METER_PROFILE_ALLOC UINT32_C(0x140)
+ /* Engine - Free a queue group meter profile. */
+ #define HWRM_ENGINE_QG_METER_PROFILE_FREE UINT32_C(0x141)
+ /* Engine - Query the meters assigned to a queue group. */
+ #define HWRM_ENGINE_QG_METER_QUERY UINT32_C(0x142)
+ /* Engine - Bind a queue group meter profile to a queue group. */
+ #define HWRM_ENGINE_QG_METER_BIND UINT32_C(0x143)
+ /* Engine - Unbind a queue group meter profile from a queue group. */
+ #define HWRM_ENGINE_QG_METER_UNBIND UINT32_C(0x144)
+ /* Engine - Bind a queue group to a function. */
+ #define HWRM_ENGINE_QG_FUNC_BIND UINT32_C(0x145)
+ /* Engine - Query the scheduling group configuration. */
+ #define HWRM_ENGINE_SG_CONFIG_QUERY UINT32_C(0x146)
+ /* Engine - Query the queue groups assigned to a scheduling group. */
+ #define HWRM_ENGINE_SG_QUERY UINT32_C(0x147)
+ /* Engine - Query the configuration of a scheduling group's meter profiles. */
+ #define HWRM_ENGINE_SG_METER_QUERY UINT32_C(0x148)
+ /* Engine - Configure a scheduling group's meter profiles. */
+ #define HWRM_ENGINE_SG_METER_CONFIG UINT32_C(0x149)
+ /* Engine - Bind a queue group to a scheduling group. */
+ #define HWRM_ENGINE_SG_QG_BIND UINT32_C(0x14a)
+ /* Engine - Unbind a queue group from its scheduling group. */
+ #define HWRM_ENGINE_QG_SG_UNBIND UINT32_C(0x14b)
+ /* Engine - Query the Engine configuration. */
+ #define HWRM_ENGINE_CONFIG_QUERY UINT32_C(0x154)
+ /* Engine - Configure the statistics accumulator for an Engine. */
+ #define HWRM_ENGINE_STATS_CONFIG UINT32_C(0x155)
+ /* Engine - Clear the statistics accumulator for an Engine. */
+ #define HWRM_ENGINE_STATS_CLEAR UINT32_C(0x156)
+ /* Engine - Query the statistics accumulator for an Engine. */
+ #define HWRM_ENGINE_STATS_QUERY UINT32_C(0x157)
+ /* Engine - Allocate an Engine RQ. */
+ #define HWRM_ENGINE_RQ_ALLOC UINT32_C(0x15e)
+ /* Engine - Free an Engine RQ. */
+ #define HWRM_ENGINE_RQ_FREE UINT32_C(0x15f)
+ /* Engine - Allocate an Engine CQ. */
+ #define HWRM_ENGINE_CQ_ALLOC UINT32_C(0x160)
+ /* Engine - Free an Engine CQ. */
+ #define HWRM_ENGINE_CQ_FREE UINT32_C(0x161)
+ /* Engine - Allocate an NQ. */
+ #define HWRM_ENGINE_NQ_ALLOC UINT32_C(0x162)
+ /* Engine - Free an NQ. */
+ #define HWRM_ENGINE_NQ_FREE UINT32_C(0x163)
+ /* Engine - Set the on-die RQE credit update location. */
+ #define HWRM_ENGINE_ON_DIE_RQE_CREDITS UINT32_C(0x164)
+ /* Experimental */
+ #define HWRM_FUNC_RESOURCE_QCAPS UINT32_C(0x190)
+ /* Experimental */
+ #define HWRM_FUNC_VF_RESOURCE_CFG UINT32_C(0x191)
+ /* Experimental */
+ #define HWRM_FUNC_BACKING_STORE_QCAPS UINT32_C(0x192)
+ /* Experimental */
+ #define HWRM_FUNC_BACKING_STORE_CFG UINT32_C(0x193)
+ /* Experimental */
+ #define HWRM_FUNC_BACKING_STORE_QCFG UINT32_C(0x194)
+ /* Experimental */
+ #define HWRM_SELFTEST_QLIST UINT32_C(0x200)
+ /* Experimental */
+ #define HWRM_SELFTEST_EXEC UINT32_C(0x201)
+ /* Experimental */
+ #define HWRM_SELFTEST_IRQ UINT32_C(0x202)
+ /* Experimental */
+ #define HWRM_SELFTEST_RETRIEVE_SERDES_DATA UINT32_C(0x203)
+ /* Experimental */
+ #define HWRM_PCIE_QSTATS UINT32_C(0x204)
+ /* Experimental */
+ #define HWRM_DBG_READ_DIRECT UINT32_C(0xff10)
+ /* Experimental */
+ #define HWRM_DBG_READ_INDIRECT UINT32_C(0xff11)
+ /* Experimental */
+ #define HWRM_DBG_WRITE_DIRECT UINT32_C(0xff12)
+ /* Experimental */
+ #define HWRM_DBG_WRITE_INDIRECT UINT32_C(0xff13)
+ #define HWRM_DBG_DUMP UINT32_C(0xff14)
+ /* Experimental */
+ #define HWRM_DBG_ERASE_NVM UINT32_C(0xff15)
+ /* Experimental */
+ #define HWRM_DBG_CFG UINT32_C(0xff16)
+ /* Experimental */
+ #define HWRM_DBG_COREDUMP_LIST UINT32_C(0xff17)
+ /* Experimental */
+ #define HWRM_DBG_COREDUMP_INITIATE UINT32_C(0xff18)
+ /* Experimental */
+ #define HWRM_DBG_COREDUMP_RETRIEVE UINT32_C(0xff19)
+ /* */
+ #define HWRM_DBG_I2C_CMD UINT32_C(0xff1b)
+ /* Experimental */
+ #define HWRM_NVM_FACTORY_DEFAULTS UINT32_C(0xffee)
+ #define HWRM_NVM_VALIDATE_OPTION UINT32_C(0xffef)
+ #define HWRM_NVM_FLUSH UINT32_C(0xfff0)
+ #define HWRM_NVM_GET_VARIABLE UINT32_C(0xfff1)
+ #define HWRM_NVM_SET_VARIABLE UINT32_C(0xfff2)
+ #define HWRM_NVM_INSTALL_UPDATE UINT32_C(0xfff3)
+ #define HWRM_NVM_MODIFY UINT32_C(0xfff4)
+ #define HWRM_NVM_VERIFY_UPDATE UINT32_C(0xfff5)
+ #define HWRM_NVM_GET_DEV_INFO UINT32_C(0xfff6)
+ #define HWRM_NVM_ERASE_DIR_ENTRY UINT32_C(0xfff7)
+ #define HWRM_NVM_MOD_DIR_ENTRY UINT32_C(0xfff8)
+ #define HWRM_NVM_FIND_DIR_ENTRY UINT32_C(0xfff9)
+ #define HWRM_NVM_GET_DIR_ENTRIES UINT32_C(0xfffa)
+ #define HWRM_NVM_GET_DIR_INFO UINT32_C(0xfffb)
+ #define HWRM_NVM_RAW_DUMP UINT32_C(0xfffc)
+ #define HWRM_NVM_READ UINT32_C(0xfffd)
+ #define HWRM_NVM_WRITE UINT32_C(0xfffe)
+ #define HWRM_NVM_RAW_WRITE_BLK UINT32_C(0xffff)
+ #define HWRM_LAST HWRM_NVM_RAW_WRITE_BLK
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Return Codes */
+/* ret_codes (size:64b/8B) */
+struct ret_codes {
+ uint16_t error_code;
+ /* Request was successfully executed by the HWRM. */
+ #define HWRM_ERR_CODE_SUCCESS UINT32_C(0x0)
+ /* The HWRM failed to execute the request. */
+ #define HWRM_ERR_CODE_FAIL UINT32_C(0x1)
+ /*
+ * The request contains invalid argument(s) or input
+ * parameters.
+ */
+ #define HWRM_ERR_CODE_INVALID_PARAMS UINT32_C(0x2)
+ /*
+ * The requester is not allowed to access the requested
+ * resource. This error code shall be provided in a
+ * response to a request to query or modify an existing
+ * resource that is not accessible by the requester.
+ */
+ #define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED UINT32_C(0x3)
+ /*
+ * The HWRM is unable to allocate the requested resource.
+ * This code only applies to requests for HWRM resource
+ * allocations.
+ */
+ #define HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR UINT32_C(0x4)
+ /*
+ * Invalid combination of flags is specified in the
+ * request.
+ */
+ #define HWRM_ERR_CODE_INVALID_FLAGS UINT32_C(0x5)
+ /*
+ * Invalid combination of enables fields is specified in
+ * the request.
+ */
+ #define HWRM_ERR_CODE_INVALID_ENABLES UINT32_C(0x6)
+ /*
+ * Request contains a required TLV that is not supported by
+ * the installed version of firmware.
+ */
+ #define HWRM_ERR_CODE_UNSUPPORTED_TLV UINT32_C(0x7)
+ /*
+ * No firmware buffer available to accept the request. Driver
+ * should retry the request.
+ */
+ #define HWRM_ERR_CODE_NO_BUFFER UINT32_C(0x8)
+ /*
+ * Generic HWRM execution error that represents an
+ * internal error.
+ */
+ #define HWRM_ERR_CODE_HWRM_ERROR UINT32_C(0xf)
+ /* Unknown error */
+ #define HWRM_ERR_CODE_UNKNOWN_ERR UINT32_C(0xfffe)
+ /* Unsupported or invalid command */
+ #define HWRM_ERR_CODE_CMD_NOT_SUPPORTED UINT32_C(0xffff)
+ #define HWRM_ERR_CODE_LAST \
+ HWRM_ERR_CODE_CMD_NOT_SUPPORTED
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output */
+/* hwrm_err_output (size:128b/16B) */
+struct hwrm_err_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;
+ /* debug info for this error response. */
+ uint32_t opaque_0;
+ /* debug info for this error response. */
+ uint16_t opaque_1;
+ /*
+ * In the case of an error response, command specific error
+ * code is returned in this field.
+ */
+ uint8_t cmd_err;
+ /*
+ * 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));
+/*
+ * 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_NA_SIGNATURE ((uint32_t)(-1))
+/* hwrm_func_buf_rgtr */
+#define HWRM_MAX_REQ_LEN 128
+/* hwrm_selftest_qlist */
+#define HWRM_MAX_RESP_LEN 280
+/* 7 bit indirection table index. */
+#define HW_HASH_INDEX_SIZE 0x80
+#define HW_HASH_KEY_SIZE 40
+/* valid key for HWRM response */
+#define HWRM_RESP_VALID_KEY 1
+#define HWRM_VERSION_MAJOR 1
+#define HWRM_VERSION_MINOR 9
+#define HWRM_VERSION_UPDATE 2
+/* non-zero means beta version */
+#define HWRM_VERSION_RSVD 9
+#define HWRM_VERSION_STR "1.9.2.9"
+
+/****************
+ * hwrm_ver_get *
+ ****************/
+
+
+/* hwrm_ver_get_input (size:192b/24B) */
+struct hwrm_ver_get_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ 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));
+
+/* hwrm_ver_get_output (size:1408b/176B) */
+struct hwrm_ver_get_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ 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_8b;
+ /*
+ * 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 2 in this field.
+ */
+ uint8_t hwrm_intf_min_8b;
+ /*
+ * 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 2 in this field.
+ */
+ uint8_t hwrm_intf_upd_8b;
+ uint8_t hwrm_intf_rsvd_8b;
+ /*
+ * 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_8b;
+ /*
+ * 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_8b;
+ /*
+ * 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_8b;
+ /*
+ * 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_8b;
+ /*
+ * This field represents the major version of mgmt firmware.
+ * A change in major version represents a major release.
+ */
+ uint8_t mgmt_fw_maj_8b;
+ /*
+ * This field represents the minor version of mgmt firmware.
+ * A change in minor version represents significant
+ * functionality changes.
+ */
+ uint8_t mgmt_fw_min_8b;
+ /*
+ * This field represents the build version of mgmt firmware.
+ * A change in update version represents bug fixes.
+ */
+ uint8_t mgmt_fw_bld_8b;
+ /*
+ * 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_8b;
+ /*
+ * This field represents the major version of network
+ * control firmware.
+ * A change in major version represents a major release.
+ */
+ uint8_t netctrl_fw_maj_8b;
+ /*
+ * This field represents the minor version of network
+ * control firmware.
+ * A change in minor version represents significant
+ * functionality changes.
+ */
+ uint8_t netctrl_fw_min_8b;
+ /*
+ * This field represents the build version of network
+ * control firmware.
+ * A change in update version represents bug fixes.
+ */
+ uint8_t netctrl_fw_bld_8b;
+ /*
+ * 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_8b;
+ /*
+ * This field is used to indicate device's capabilities and
+ * configurations.
+ */
+ uint32_t dev_caps_cfg;
+ /*
+ * If set to 1, then secure firmware update behavior
+ * is supported.
+ * If set to 0, then secure firmware update behavior is
+ * not supported.
+ */
+ #define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SECURE_FW_UPD_SUPPORTED \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, then firmware based DCBX agent is supported.
+ * If set to 0, then firmware based DCBX agent capability
+ * is not supported on this device.
+ */
+ #define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FW_DCBX_AGENT_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, then HWRM short command format is supported.
+ * If set to 0, then HWRM short command format is not supported.
+ */
+ #define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED \
+ UINT32_C(0x4)
+ /*
+ * If set to 1, then HWRM short command format is required.
+ * If set to 0, then HWRM short command format is not required.
+ */
+ #define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_REQUIRED \
+ UINT32_C(0x8)
+ /*
+ * This field represents the major version of RoCE firmware.
+ * A change in major version represents a major release.
+ */
+ uint8_t roce_fw_maj_8b;
+ /*
+ * This field represents the minor version of RoCE firmware.
+ * A change in minor version represents significant
+ * functionality changes.
+ */
+ uint8_t roce_fw_min_8b;
+ /*
+ * This field represents the build version of RoCE firmware.
+ * A change in update version represents bug fixes.
+ */
+ uint8_t roce_fw_bld_8b;
+ /*
+ * 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_8b;
+ /*
+ * This field represents the name of HWRM FW (ASCII chars
+ * with NULL at the end).
+ */
+ char hwrm_fw_name[16];
+ /*
+ * This field represents the name of mgmt FW (ASCII chars
+ * with NULL at the end).
+ */
+ char mgmt_fw_name[16];
+ /*
+ * This field represents the name of network control
+ * firmware (ASCII chars with 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.
+ */
+ uint8_t reserved2[16];
+ /*
+ * This field represents the name of RoCE FW (ASCII chars
+ * with 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. */
+ uint8_t chip_platform_type;
+ /* ASIC */
+ #define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_ASIC UINT32_C(0x0)
+ /* FPGA platform of the chip. */
+ #define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_FPGA UINT32_C(0x1)
+ /* Palladium platform of the chip. */
+ #define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM UINT32_C(0x2)
+ #define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_LAST \
+ HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM
+ /*
+ * 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.
+ */
+ uint16_t max_resp_len;
+ /*
+ * This field returns the default request timeout value in
+ * milliseconds.
+ */
+ uint16_t def_req_timeout;
+ /*
+ * This field will indicate if any subsystems is not fully
+ * initialized.
+ */
+ uint8_t flags;
+ /*
+ * If set to 1, device is not ready.
+ * If set to 0, device is ready to accept all HWRM commands.
+ */
+ #define HWRM_VER_GET_OUTPUT_FLAGS_DEV_NOT_RDY UINT32_C(0x1)
+ /*
+ * If set to 1, external version present.
+ * If set to 0, external version not present.
+ */
+ #define HWRM_VER_GET_OUTPUT_FLAGS_EXT_VER_AVAIL UINT32_C(0x2)
+ uint8_t unused_0[2];
+ /*
+ * For backward compatibility this field must be set to 1.
+ * Older drivers might look for this field to be 1 before
+ * processing the message.
+ */
+ uint8_t always_1;
+ /*
+ * 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.
+ */
+ uint16_t hwrm_intf_major;
+ /*
+ * 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 2 in this field.
+ */
+ uint16_t hwrm_intf_minor;
+ /*
+ * 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 2 in this field.
+ */
+ uint16_t hwrm_intf_build;
+ /*
+ * This field represents the patch version of HWRM interface
+ * specification supported by the HWRM implementation.
+ */
+ uint16_t hwrm_intf_patch;
+ /*
+ * This field represents the major version of HWRM firmware.
+ * A change in firmware major version represents a major
+ * firmware release.
+ */
+ uint16_t hwrm_fw_major;
+ /*
+ * This field represents the minor version of HWRM firmware.
+ * A change in firmware minor version represents significant
+ * firmware functionality changes.
+ */
+ uint16_t hwrm_fw_minor;
+ /*
+ * This field represents the build version of HWRM firmware.
+ * A change in firmware build version represents bug fixes to
+ * a released firmware.
+ */
+ uint16_t hwrm_fw_build;
+ /*
+ * 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.
+ */
+ uint16_t hwrm_fw_patch;
+ /*
+ * This field represents the major version of mgmt firmware.
+ * A change in major version represents a major release.
+ */
+ uint16_t mgmt_fw_major;
+ /*
+ * This field represents the minor version of HWRM firmware.
+ * A change in firmware minor version represents significant
+ * firmware functionality changes.
+ */
+ uint16_t mgmt_fw_minor;
+ /*
+ * This field represents the build version of mgmt firmware.
+ * A change in update version represents bug fixes.
+ */
+ uint16_t mgmt_fw_build;
+ /*
+ * 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.
+ */
+ uint16_t mgmt_fw_patch;
+ /*
+ * This field represents the major version of network control
+ * firmware. A change in major version represents
+ * a major release.
+ */
+ uint16_t netctrl_fw_major;
+ /*
+ * This field represents the minor version of network control
+ * firmware. A change in minor version represents significant
+ * functionality changes.
+ */
+ uint16_t netctrl_fw_minor;
+ /*
+ * This field represents the build version of network control
+ * firmware. A change in update version represents bug fixes.
+ */
+ uint16_t netctrl_fw_build;
+ /*
+ * 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
+ */
+ uint16_t netctrl_fw_patch;
+ /*
+ * This field represents the major version of RoCE firmware.
+ * A change in major version represents a major release.
+ */
+ uint16_t roce_fw_major;
+ /*
+ * This field represents the minor version of RoCE firmware.
+ * A change in minor version represents significant
+ * functionality changes.
+ */
+ uint16_t roce_fw_minor;
+ /*
+ * This field represents the build version of RoCE firmware.
+ * A change in update version represents bug fixes.
+ */
+ uint16_t roce_fw_build;
+ /*
+ * 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
+ */
+ uint16_t roce_fw_patch;
+ /*
+ * This field returns the maximum extended request length acceptable
+ * by the device which allows requests greater than mailbox size when
+ * used with the short cmd request format.
+ */
+ uint16_t max_ext_req_len;
+ uint8_t unused_1[5];
+ /*
+ * 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));
+
+/* bd_base (size:64b/8B) */
+struct bd_base {
+ uint8_t type;
+ /* This value identifies the type of buffer descriptor. */
+ #define BD_BASE_TYPE_MASK UINT32_C(0x3f)
+ #define BD_BASE_TYPE_SFT 0
+ /*
+ * Indicates that this BD is 16B long and is used for
+ * normal L2 packet transmission.
+ */
+ #define BD_BASE_TYPE_TX_BD_SHORT UINT32_C(0x0)
+ /*
+ * Indicates that this BD is 1BB long and is an empty
+ * TX BD. Not valid for use by the driver.
+ */
+ #define BD_BASE_TYPE_TX_BD_EMPTY UINT32_C(0x1)
+ /*
+ * Indicates that this BD is 16B long and is an RX Producer
+ * (ie. empty) buffer descriptor.
+ */
+ #define BD_BASE_TYPE_RX_PROD_PKT UINT32_C(0x4)
+ /*
+ * Indicates that this BD is 16B long and is an RX
+ * Producer Buffer BD.
+ */
+ #define BD_BASE_TYPE_RX_PROD_BFR UINT32_C(0x5)
+ /*
+ * Indicates that this BD is 16B long and is an
+ * RX Producer Assembly Buffer Descriptor.
+ */
+ #define BD_BASE_TYPE_RX_PROD_AGG UINT32_C(0x6)
+ /*
+ * Indicates that this BD is 32B long and is used for
+ * normal L2 packet transmission.
+ */
+ #define BD_BASE_TYPE_TX_BD_LONG UINT32_C(0x10)
+ #define BD_BASE_TYPE_LAST BD_BASE_TYPE_TX_BD_LONG
+ uint8_t unused_1[7];
+} __attribute__((packed));
+
+/* tx_bd_short (size:128b/16B) */
+struct tx_bd_short {
+ /*
+ * All bits in this field must be valid on the first BD of a packet.
+ * Only the packet_end bit must be valid for the remaining BDs
+ * of a packet.
+ */
+ uint16_t flags_type;
+ /* This value identifies the type of buffer descriptor. */
+ #define TX_BD_SHORT_TYPE_MASK UINT32_C(0x3f)
+ #define TX_BD_SHORT_TYPE_SFT 0
+ /*
+ * Indicates that this BD is 16B long and is used for
+ * normal L2 packet transmission.
+ */
+ #define TX_BD_SHORT_TYPE_TX_BD_SHORT UINT32_C(0x0)
+ #define TX_BD_SHORT_TYPE_LAST TX_BD_SHORT_TYPE_TX_BD_SHORT
+ /*
+ * All bits in this field must be valid on the first BD of a packet.
+ * Only the packet_end bit must be valid for the remaining BDs
+ * of a packet.
+ */
+ #define TX_BD_SHORT_FLAGS_MASK UINT32_C(0xffc0)
+ #define TX_BD_SHORT_FLAGS_SFT 6
+ /*
+ * If set to 1, the packet ends with the data in the buffer
+ * pointed to by this descriptor. This flag must be
+ * valid on every BD.
+ */
+ #define TX_BD_SHORT_FLAGS_PACKET_END UINT32_C(0x40)
+ /*
+ * If set to 1, the device will not generate a completion for
+ * this transmit packet unless there is an error in it's
+ * processing.
+ * If this bit
+ * is set to 0, then the packet will be completed normally.
+ *
+ * This bit must be valid only on the first BD of a packet.
+ */
+ #define TX_BD_SHORT_FLAGS_NO_CMPL UINT32_C(0x80)
+ /*
+ * This value indicates how many 16B BD locations are consumed
+ * in the ring by this packet.
+ * A value of 1 indicates that this BD is the only BD (and that
+ * the it is a short BD). A value
+ * of 3 indicates either 3 short BDs or 1 long BD and one short
+ * BD in the packet. A value of 0 indicates
+ * that there are 32 BD locations in the packet (the maximum).
+ *
+ * This field is valid only on the first BD of a packet.
+ */
+ #define TX_BD_SHORT_FLAGS_BD_CNT_MASK UINT32_C(0x1f00)
+ #define TX_BD_SHORT_FLAGS_BD_CNT_SFT 8
+ /*
+ * This value is a hint for the length of the entire packet.
+ * It is used by the chip to optimize internal processing.
+ *
+ * The packet will be dropped if the hint is too short.
+ *
+ * This field is valid only on the first BD of a packet.
+ */
+ #define TX_BD_SHORT_FLAGS_LHINT_MASK UINT32_C(0x6000)
+ #define TX_BD_SHORT_FLAGS_LHINT_SFT 13
+ /* indicates packet length < 512B */
+ #define TX_BD_SHORT_FLAGS_LHINT_LT512 (UINT32_C(0x0) << 13)
+ /* indicates 512 <= packet length < 1KB */
+ #define TX_BD_SHORT_FLAGS_LHINT_LT1K (UINT32_C(0x1) << 13)
+ /* indicates 1KB <= packet length < 2KB */
+ #define TX_BD_SHORT_FLAGS_LHINT_LT2K (UINT32_C(0x2) << 13)
+ /* indicates packet length >= 2KB */
+ #define TX_BD_SHORT_FLAGS_LHINT_GTE2K (UINT32_C(0x3) << 13)
+ #define TX_BD_SHORT_FLAGS_LHINT_LAST \
+ TX_BD_SHORT_FLAGS_LHINT_GTE2K
+ /*
+ * If set to 1, the device immediately updates the Send Consumer
+ * Index after the buffer associated with this descriptor has
+ * been transferred via DMA to NIC memory from host memory. An
+ * interrupt may or may not be generated according to the state
+ * of the interrupt avoidance mechanisms. If this bit
+ * is set to 0, then the Consumer Index is only updated as soon
+ * as one of the host interrupt coalescing conditions has been met.
+ *
+ * This bit must be valid on the first BD of a packet.
+ */
+ #define TX_BD_SHORT_FLAGS_COAL_NOW UINT32_C(0x8000)
+ /*
+ * This is the length of the host physical buffer this BD describes
+ * in bytes.
+ *
+ * This field must be valid on all BDs of a packet.
+ */
+ uint16_t len;
+ /*
+ * The opaque data field is pass through to the completion and can be
+ * used for any data that the driver wants to associate with the
+ * transmit BD.
+ *
+ * This field must be valid on the first BD of a packet.
+ */
+ uint32_t opaque;
+ /*
+ * This is the host physical address for the portion of the packet
+ * described by this TX BD.
+ *
+ * This value must be valid on all BDs of a packet.
+ */
+ uint64_t address;
+} __attribute__((packed));
+
+/* tx_bd_long (size:128b/16B) */
+struct tx_bd_long {
+ /* This value identifies the type of buffer descriptor. */
+ uint16_t flags_type;
+ /*
+ * This value indicates the type of buffer descriptor.
+ * packet.
+ */
+ #define TX_BD_LONG_TYPE_MASK UINT32_C(0x3f)
+ #define TX_BD_LONG_TYPE_SFT 0
+ /*
+ * Indicates that this BD is 32B long and is used for
+ * normal L2 packet transmission.
+ */
+ #define TX_BD_LONG_TYPE_TX_BD_LONG UINT32_C(0x10)
+ #define TX_BD_LONG_TYPE_LAST TX_BD_LONG_TYPE_TX_BD_LONG
+ /*
+ * All bits in this field must be valid on the first BD of a packet.
+ * Only the packet_end bit must be valid for the remaining BDs
+ * of a packet.
+ */
+ #define TX_BD_LONG_FLAGS_MASK UINT32_C(0xffc0)
+ #define TX_BD_LONG_FLAGS_SFT 6
+ /*
+ * If set to 1, the packet ends with the data in the buffer
+ * pointed to by this descriptor. This flag must be
+ * valid on every BD.
+ */
+ #define TX_BD_LONG_FLAGS_PACKET_END UINT32_C(0x40)
+ /*
+ * If set to 1, the device will not generate a completion for
+ * this transmit packet unless there is an error in it's
+ * processing.
+ * If this bit
+ * is set to 0, then the packet will be completed normally.
+ *
+ * This bit must be valid only on the first BD of a packet.
+ */
+ #define TX_BD_LONG_FLAGS_NO_CMPL UINT32_C(0x80)
+ /*
+ * This value indicates how many 16B BD locations are consumed
+ * in the ring by this packet.
+ * A value of 1 indicates that this BD is the only BD (and that
+ * the it is a short BD). A value
+ * of 3 indicates either 3 short BDs or 1 long BD and one short
+ * BD in the packet. A value of 0 indicates
+ * that there are 32 BD locations in the packet (the maximum).
+ *
+ * This field is valid only on the first BD of a packet.
+ */
+ #define TX_BD_LONG_FLAGS_BD_CNT_MASK UINT32_C(0x1f00)
+ #define TX_BD_LONG_FLAGS_BD_CNT_SFT 8
+ /*
+ * This value is a hint for the length of the entire packet.
+ * It is used by the chip to optimize internal processing.
+ *
+ * The packet will be dropped if the hint is too short.
+ *
+ * This field is valid only on the first BD of a packet.
+ */
+ #define TX_BD_LONG_FLAGS_LHINT_MASK UINT32_C(0x6000)
+ #define TX_BD_LONG_FLAGS_LHINT_SFT 13
+ /* indicates packet length < 512B */
+ #define TX_BD_LONG_FLAGS_LHINT_LT512 (UINT32_C(0x0) << 13)
+ /* indicates 512 <= packet length < 1KB */
+ #define TX_BD_LONG_FLAGS_LHINT_LT1K (UINT32_C(0x1) << 13)
+ /* indicates 1KB <= packet length < 2KB */
+ #define TX_BD_LONG_FLAGS_LHINT_LT2K (UINT32_C(0x2) << 13)
+ /* indicates packet length >= 2KB */
+ #define TX_BD_LONG_FLAGS_LHINT_GTE2K (UINT32_C(0x3) << 13)
+ #define TX_BD_LONG_FLAGS_LHINT_LAST TX_BD_LONG_FLAGS_LHINT_GTE2K
+ /*
+ * If set to 1, the device immediately updates the Send Consumer
+ * Index after the buffer associated with this descriptor has
+ * been transferred via DMA to NIC memory from host memory. An
+ * interrupt may or may not be generated according to the state
+ * of the interrupt avoidance mechanisms. If this bit
+ * is set to 0, then the Consumer Index is only updated as soon
+ * as one of the host interrupt coalescing conditions has been met.
+ *
+ * This bit must be valid on the first BD of a packet.
+ */
+ #define TX_BD_LONG_FLAGS_COAL_NOW UINT32_C(0x8000)
+ /*
+ * This is the length of the host physical buffer this BD describes
+ * in bytes.
+ *
+ * This field must be valid on all BDs of a packet.
+ */
+ uint16_t len;
+ /*
+ * The opaque data field is pass through to the completion and can be
+ * used for any data that the driver wants to associate with the
+ * transmit BD.
+ *
+ * This field must be valid on the first BD of a packet.
+ */
+ uint32_t opaque;
+ /*
+ * This is the host physical address for the portion of the packet
+ * described by this TX BD.
+ *
+ * This value must be valid on all BDs of a packet.
+ */
+ uint64_t address;
+} __attribute__((packed));
+
+/* tx_bd_long_hi (size:128b/16B) */
+struct tx_bd_long_hi {
+ /*
+ * All bits in this field must be valid on the first BD of a packet.
+ * Their value on other BDs of the packet will be ignored.
+ */
+ uint16_t lflags;
+ /*
+ * If set to 1, the controller replaces the TCP/UPD checksum
+ * fields of normal TCP/UPD checksum, or the inner TCP/UDP
+ * checksum field of the encapsulated TCP/UDP packets with the
+ * hardware calculated TCP/UDP checksum for the packet associated
+ * with this descriptor. The flag is ignored if the LSO flag is set.
+ *
+ * This bit must be valid on the first BD of a packet.
+ */
+ #define TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM UINT32_C(0x1)
+ /*
+ * If set to 1, the controller replaces the IP checksum of the
+ * normal packets, or the inner IP checksum of the encapsulated
+ * packets with the hardware calculated IP checksum for the
+ * packet associated with this descriptor.
+ *
+ * This bit must be valid on the first BD of a packet.
+ */
+ #define TX_BD_LONG_LFLAGS_IP_CHKSUM UINT32_C(0x2)
+ /*
+ * If set to 1, the controller will not append an Ethernet CRC
+ * to the end of the frame.
+ *
+ * This bit must be valid on the first BD of a packet.
+ *
+ * Packet must be 64B or longer when this flag is set. It is not
+ * useful to use this bit with any form of TX offload such as
+ * CSO or LSO. The intent is that the packet from the host already
+ * has a valid Ethernet CRC on the packet.
+ */
+ #define TX_BD_LONG_LFLAGS_NOCRC UINT32_C(0x4)
+ /*
+ * If set to 1, the device will record the time at which the packet
+ * was actually transmitted at the TX MAC.
+ *
+ * This bit must be valid on the first BD of a packet.
+ */
+ #define TX_BD_LONG_LFLAGS_STAMP UINT32_C(0x8)
+ /*
+ * If set to 1, The controller replaces the tunnel IP checksum
+ * field with hardware calculated IP checksum for the IP header
+ * of the packet associated with this descriptor.
+ *
+ * For outer UDP checksum, global outer UDP checksum TE_NIC register
+ * needs to be enabled. If the global outer UDP checksum TE_NIC register
+ * bit is set, outer UDP checksum will be calculated for the following
+ * cases:
+ * 1. Packets with tcp_udp_chksum flag set to offload checksum for inner
+ * packet AND the inner packet is TCP/UDP. If the inner packet is ICMP for
+ * example (non-TCP/UDP), even if the tcp_udp_chksum is set, the outer UDP
+ * checksum will not be calculated.
+ * 2. Packets with lso flag set which implies inner TCP checksum calculation
+ * as part of LSO operation.
+ */
+ #define TX_BD_LONG_LFLAGS_T_IP_CHKSUM UINT32_C(0x10)
+ /*
+ * If set to 1, the device will treat this packet with LSO(Large
+ * Send Offload) processing for both normal or encapsulated
+ * packets, which is a form of TCP segmentation. When this bit
+ * is 1, the hdr_size and mss fields must be valid. The driver
+ * doesn't need to set t_ip_chksum, ip_chksum, and tcp_udp_chksum
+ * flags since the controller will replace the appropriate
+ * checksum fields for segmented packets.
+ *
+ * When this bit is 1, the hdr_size and mss fields must be valid.
+ */
+ #define TX_BD_LONG_LFLAGS_LSO UINT32_C(0x20)
+ /*
+ * If set to zero when LSO is '1', then the IPID will be treated
+ * as a 16b number and will be wrapped if it exceeds a value of
+ * 0xffff.
+ *
+ * If set to one when LSO is '1', then the IPID will be treated
+ * as a 15b number and will be wrapped if it exceeds a value 0f
+ * 0x7fff.
+ */
+ #define TX_BD_LONG_LFLAGS_IPID_FMT UINT32_C(0x40)
+ /*
+ * If set to zero when LSO is '1', then the IPID of the tunnel
+ * IP header will not be modified during LSO operations.
+ *
+ * If set to one when LSO is '1', then the IPID of the tunnel
+ * IP header will be incremented for each subsequent segment of an
+ * LSO operation.
+ *
+ * The flag is ignored if the LSO packet is a normal (non-tunneled)
+ * TCP packet.
+ */
+ #define TX_BD_LONG_LFLAGS_T_IPID UINT32_C(0x80)
+ /*
+ * If set to '1', then the RoCE ICRC will be appended to the
+ * packet. Packet must be a valid RoCE format packet.
+ */
+ #define TX_BD_LONG_LFLAGS_ROCE_CRC UINT32_C(0x100)
+ /*
+ * If set to '1', then the FCoE CRC will be appended to the
+ * packet. Packet must be a valid FCoE format packet.
+ */
+ #define TX_BD_LONG_LFLAGS_FCOE_CRC UINT32_C(0x200)
+ uint16_t hdr_size;
+ /*
+ * When LSO is '1', this field must contain the offset of the
+ * TCP payload from the beginning of the packet in as
+ * 16b words. In case of encapsulated/tunneling packet, this field
+ * contains the offset of the inner TCP payload from beginning of the
+ * packet as 16-bit words.
+ *
+ * This value must be valid on the first BD of a packet.
+ */
+ #define TX_BD_LONG_HDR_SIZE_MASK UINT32_C(0x1ff)
+ #define TX_BD_LONG_HDR_SIZE_SFT 0
+ uint32_t mss;
+ /*
+ * This is the MSS value that will be used to do the LSO processing.
+ * The value is the length in bytes of the TCP payload for each
+ * segment generated by the LSO operation.
+ *
+ * This value must be valid on the first BD of a packet.
+ */
+ #define TX_BD_LONG_MSS_MASK UINT32_C(0x7fff)
+ #define TX_BD_LONG_MSS_SFT 0
+ uint16_t unused2;
+ /*
+ * This value selects a CFA action to perform on the packet.
+ * Set this value to zero if no CFA action is desired.
+ *
+ * This value must be valid on the first BD of a packet.
+ */
+ uint16_t cfa_action;
+ /*
+ * This value is action meta-data that defines CFA edit operations
+ * that are done in addition to any action editing.
+ */
+ uint32_t cfa_meta;
+ /* When key=1, This is the VLAN tag VID value. */
+ #define TX_BD_LONG_CFA_META_VLAN_VID_MASK UINT32_C(0xfff)
+ #define TX_BD_LONG_CFA_META_VLAN_VID_SFT 0
+ /* When key=1, This is the VLAN tag DE value. */
+ #define TX_BD_LONG_CFA_META_VLAN_DE UINT32_C(0x1000)
+ /* When key=1, This is the VLAN tag PRI value. */
+ #define TX_BD_LONG_CFA_META_VLAN_PRI_MASK UINT32_C(0xe000)
+ #define TX_BD_LONG_CFA_META_VLAN_PRI_SFT 13
+ /* When key=1, This is the VLAN tag TPID select value. */
+ #define TX_BD_LONG_CFA_META_VLAN_TPID_MASK UINT32_C(0x70000)
+ #define TX_BD_LONG_CFA_META_VLAN_TPID_SFT 16
+ /* 0x88a8 */
+ #define TX_BD_LONG_CFA_META_VLAN_TPID_TPID88A8 (UINT32_C(0x0) << 16)
+ /* 0x8100 */
+ #define TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100 (UINT32_C(0x1) << 16)
+ /* 0x9100 */
+ #define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9100 (UINT32_C(0x2) << 16)
+ /* 0x9200 */
+ #define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9200 (UINT32_C(0x3) << 16)
+ /* 0x9300 */
+ #define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9300 (UINT32_C(0x4) << 16)
+ /* Value programmed in CFA VLANTPID register. */
+ #define TX_BD_LONG_CFA_META_VLAN_TPID_TPIDCFG (UINT32_C(0x5) << 16)
+ #define TX_BD_LONG_CFA_META_VLAN_TPID_LAST \
+ TX_BD_LONG_CFA_META_VLAN_TPID_TPIDCFG
+ /* When key=1, This is the VLAN tag TPID select value. */
+ #define TX_BD_LONG_CFA_META_VLAN_RESERVED_MASK UINT32_C(0xff80000)
+ #define TX_BD_LONG_CFA_META_VLAN_RESERVED_SFT 19
+ /*
+ * This field identifies the type of edit to be performed
+ * on the packet.
+ *
+ * This value must be valid on the first BD of a packet.
+ */
+ #define TX_BD_LONG_CFA_META_KEY_MASK UINT32_C(0xf0000000)
+ #define TX_BD_LONG_CFA_META_KEY_SFT 28
+ /* No editing */
+ #define TX_BD_LONG_CFA_META_KEY_NONE (UINT32_C(0x0) << 28)
+ /*
+ * - meta[17:16] - TPID select value (0 = 0x8100).
+ * - meta[15:12] - PRI/DE value.
+ * - meta[11:0] - VID value.
+ */
+ #define TX_BD_LONG_CFA_META_KEY_VLAN_TAG (UINT32_C(0x1) << 28)
+ #define TX_BD_LONG_CFA_META_KEY_LAST \
+ TX_BD_LONG_CFA_META_KEY_VLAN_TAG
+} __attribute__((packed));
+
+/* tx_bd_empty (size:128b/16B) */
+struct tx_bd_empty {
+ /* This value identifies the type of buffer descriptor. */
+ uint8_t type;
+ #define TX_BD_EMPTY_TYPE_MASK UINT32_C(0x3f)
+ #define TX_BD_EMPTY_TYPE_SFT 0
+ /*
+ * Indicates that this BD is 1BB long and is an empty
+ * TX BD. Not valid for use by the driver.
+ */
+ #define TX_BD_EMPTY_TYPE_TX_BD_EMPTY UINT32_C(0x1)
+ #define TX_BD_EMPTY_TYPE_LAST TX_BD_EMPTY_TYPE_TX_BD_EMPTY
+ uint8_t unused_1[3];
+ uint8_t unused_2;
+ uint8_t unused_3[3];
+ uint8_t unused_4[8];
+} __attribute__((packed));
+
+/* rx_prod_pkt_bd (size:128b/16B) */
+struct rx_prod_pkt_bd {
+ /* This value identifies the type of buffer descriptor. */
+ uint16_t flags_type;
+ /* This value identifies the type of buffer descriptor. */
+ #define RX_PROD_PKT_BD_TYPE_MASK UINT32_C(0x3f)
+ #define RX_PROD_PKT_BD_TYPE_SFT 0
+ /*
+ * Indicates that this BD is 16B long and is an RX Producer
+ * (ie. empty) buffer descriptor.
+ */
+ #define RX_PROD_PKT_BD_TYPE_RX_PROD_PKT UINT32_C(0x4)
+ #define RX_PROD_PKT_BD_TYPE_LAST \
+ RX_PROD_PKT_BD_TYPE_RX_PROD_PKT
+ #define RX_PROD_PKT_BD_FLAGS_MASK UINT32_C(0xffc0)
+ #define RX_PROD_PKT_BD_FLAGS_SFT 6
+ /*
+ * If set to 1, the packet will be placed at the address plus
+ * 2B. The 2 Bytes of padding will be written as zero.
+ */
+ #define RX_PROD_PKT_BD_FLAGS_SOP_PAD UINT32_C(0x40)
+ /*
+ * If set to 1, the packet write will be padded out to the
+ * nearest cache-line with zero value padding.
+ */
+ #define RX_PROD_PKT_BD_FLAGS_EOP_PAD UINT32_C(0x80)
+ /*
+ * This value is the number of additional buffers in the ring that
+ * describe the buffer space to be consumed for the this packet.
+ * If the value is zero, then the packet must fit within the
+ * space described by this BD. If this value is 1 or more, it
+ * indicates how many additional "buffer" BDs are in the ring
+ * immediately following this BD to be used for the same
+ * network packet.
+ *
+ * Even if the packet to be placed does not need all the
+ * additional buffers, they will be consumed anyway.
+ */
+ #define RX_PROD_PKT_BD_FLAGS_BUFFERS_MASK UINT32_C(0x300)
+ #define RX_PROD_PKT_BD_FLAGS_BUFFERS_SFT 8
+ /*
+ * This is the length in Bytes of the host physical buffer where
+ * data for the packet may be placed in host memory.
+ */
+ uint16_t len;
+ /*
+ * The opaque data field is pass through to the completion and can be
+ * used for any data that the driver wants to associate with this
+ * receive buffer set.
+ */
+ uint32_t opaque;
+ /*
+ * This is the host physical address where data for the packet may
+ * by placed in host memory.
+ */
+ uint64_t address;
+} __attribute__((packed));
+
+/* rx_prod_bfr_bd (size:128b/16B) */
+struct rx_prod_bfr_bd {
+ /* This value identifies the type of buffer descriptor. */
+ uint16_t flags_type;
+ /* This value identifies the type of buffer descriptor. */
+ #define RX_PROD_BFR_BD_TYPE_MASK UINT32_C(0x3f)
+ #define RX_PROD_BFR_BD_TYPE_SFT 0
+ /*
+ * Indicates that this BD is 16B long and is an RX
+ * Producer Buffer BD.
+ */
+ #define RX_PROD_BFR_BD_TYPE_RX_PROD_BFR UINT32_C(0x5)
+ #define RX_PROD_BFR_BD_TYPE_LAST RX_PROD_BFR_BD_TYPE_RX_PROD_BFR
+ #define RX_PROD_BFR_BD_FLAGS_MASK UINT32_C(0xffc0)
+ #define RX_PROD_BFR_BD_FLAGS_SFT 6
+ /*
+ * This is the length in Bytes of the host physical buffer where
+ * data for the packet may be placed in host memory.
+ */
+ uint16_t len;
+ /* This field is not used. */
+ uint32_t opaque;
+ /*
+ * This is the host physical address where data for the packet may
+ * by placed in host memory.
+ */
+ uint64_t address;
+} __attribute__((packed));
+
+/* rx_prod_agg_bd (size:128b/16B) */
+struct rx_prod_agg_bd {
+ /* This value identifies the type of buffer descriptor. */
+ uint16_t flags_type;
+ /* This value identifies the type of buffer descriptor. */
+ #define RX_PROD_AGG_BD_TYPE_MASK UINT32_C(0x3f)
+ #define RX_PROD_AGG_BD_TYPE_SFT 0
+ /*
+ * Indicates that this BD is 16B long and is an
+ * RX Producer Assembly Buffer Descriptor.
+ */
+ #define RX_PROD_AGG_BD_TYPE_RX_PROD_AGG UINT32_C(0x6)
+ #define RX_PROD_AGG_BD_TYPE_LAST \
+ RX_PROD_AGG_BD_TYPE_RX_PROD_AGG
+ #define RX_PROD_AGG_BD_FLAGS_MASK UINT32_C(0xffc0)
+ #define RX_PROD_AGG_BD_FLAGS_SFT 6
+ /*
+ * If set to 1, the packet write will be padded out to the
+ * nearest cache-line with zero value padding.
+ */
+ #define RX_PROD_AGG_BD_FLAGS_EOP_PAD UINT32_C(0x40)
+ /*
+ * This is the length in Bytes of the host physical buffer where
+ * data for the packet may be placed in host memory.
+ */
+ uint16_t len;
+ /*
+ * The opaque data field is pass through to the completion and can be
+ * used for any data that the driver wants to associate with this
+ * receive assembly buffer.
+ */
+ uint32_t opaque;
+ /*
+ * This is the host physical address where data for the packet may
+ * by placed in host memory.
+ */
+ uint64_t address;
+} __attribute__((packed));
+
+/* cmpl_base (size:128b/16B) */
+struct cmpl_base {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define CMPL_BASE_TYPE_MASK UINT32_C(0x3f)
+ #define CMPL_BASE_TYPE_SFT 0
+ /*
+ * TX L2 completion:
+ * Completion of TX packet. Length = 16B
+ */
+ #define CMPL_BASE_TYPE_TX_L2 UINT32_C(0x0)
+ /*
+ * RX L2 completion:
+ * Completion of and L2 RX packet. Length = 32B
+ */
+ #define CMPL_BASE_TYPE_RX_L2 UINT32_C(0x11)
+ /*
+ * RX Aggregation Buffer completion :
+ * Completion of an L2 aggregation buffer in support of
+ * TPA, HDS, or Jumbo packet completion. Length = 16B
+ */
+ #define CMPL_BASE_TYPE_RX_AGG UINT32_C(0x12)
+ /*
+ * RX L2 TPA Start Completion:
+ * Completion at the beginning of a TPA operation.
+ * Length = 32B
+ */
+ #define CMPL_BASE_TYPE_RX_TPA_START UINT32_C(0x13)
+ /*
+ * RX L2 TPA End Completion:
+ * Completion at the end of a TPA operation.
+ * Length = 32B
+ */
+ #define CMPL_BASE_TYPE_RX_TPA_END UINT32_C(0x15)
+ /*
+ * Statistics Ejection Completion:
+ * Completion of statistics data ejection buffer.
+ * Length = 16B
+ */
+ #define CMPL_BASE_TYPE_STAT_EJECT UINT32_C(0x1a)
+ /*
+ * HWRM Command Completion:
+ * Completion of an HWRM command.
+ */
+ #define CMPL_BASE_TYPE_HWRM_DONE UINT32_C(0x20)
+ /* Forwarded HWRM Request */
+ #define CMPL_BASE_TYPE_HWRM_FWD_REQ UINT32_C(0x22)
+ /* Forwarded HWRM Response */
+ #define CMPL_BASE_TYPE_HWRM_FWD_RESP UINT32_C(0x24)
+ /* HWRM Asynchronous Event Information */
+ #define CMPL_BASE_TYPE_HWRM_ASYNC_EVENT UINT32_C(0x2e)
+ /* CQ Notification */
+ #define CMPL_BASE_TYPE_CQ_NOTIFICATION UINT32_C(0x30)
+ /* SRQ Threshold Event */
+ #define CMPL_BASE_TYPE_SRQ_EVENT UINT32_C(0x32)
+ /* DBQ Threshold Event */
+ #define CMPL_BASE_TYPE_DBQ_EVENT UINT32_C(0x34)
+ /* QP Async Notification */
+ #define CMPL_BASE_TYPE_QP_EVENT UINT32_C(0x38)
+ /* Function Async Notification */
+ #define CMPL_BASE_TYPE_FUNC_EVENT UINT32_C(0x3a)
+ #define CMPL_BASE_TYPE_LAST CMPL_BASE_TYPE_FUNC_EVENT
+ /* info1 is 16 b */
+ uint16_t info1;
+ /* info2 is 32 b */
+ uint32_t info2;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ uint32_t info3_v;
+ #define CMPL_BASE_V UINT32_C(0x1)
+ #define CMPL_BASE_INFO3_MASK UINT32_C(0xfffffffe)
+ #define CMPL_BASE_INFO3_SFT 1
+ /* info4 is 32 b */
+ uint32_t info4;
+} __attribute__((packed));
+
+/* tx_cmpl (size:128b/16B) */
+struct tx_cmpl {
+ uint16_t flags_type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define TX_CMPL_TYPE_MASK UINT32_C(0x3f)
+ #define TX_CMPL_TYPE_SFT 0
+ /*
+ * TX L2 completion:
+ * Completion of TX packet. Length = 16B
+ */
+ #define TX_CMPL_TYPE_TX_L2 UINT32_C(0x0)
+ #define TX_CMPL_TYPE_LAST TX_CMPL_TYPE_TX_L2
+ #define TX_CMPL_FLAGS_MASK UINT32_C(0xffc0)
+ #define TX_CMPL_FLAGS_SFT 6
+ /*
+ * When this bit is '1', it indicates a packet that has an
+ * error of some type. Type of error is indicated in
+ * error_flags.
+ */
+ #define TX_CMPL_FLAGS_ERROR UINT32_C(0x40)
+ /*
+ * When this bit is '1', it indicates that the packet completed
+ * was transmitted using the push acceleration data provided
+ * by the driver. When this bit is '0', it indicates that the
+ * packet had not push acceleration data written or was executed
+ * as a normal packet even though push data was provided.
+ */
+ #define TX_CMPL_FLAGS_PUSH UINT32_C(0x80)
+ /* unused1 is 16 b */
+ uint16_t unused_0;
+ /*
+ * This is a copy of the opaque field from the first TX BD of this
+ * transmitted packet.
+ */
+ uint32_t opaque;
+ uint16_t errors_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define TX_CMPL_V UINT32_C(0x1)
+ #define TX_CMPL_ERRORS_MASK UINT32_C(0xfffe)
+ #define TX_CMPL_ERRORS_SFT 1
+ /*
+ * This error indicates that there was some sort of problem
+ * with the BDs for the packet.
+ */
+ #define TX_CMPL_ERRORS_BUFFER_ERROR_MASK UINT32_C(0xe)
+ #define TX_CMPL_ERRORS_BUFFER_ERROR_SFT 1
+ /* No error */
+ #define TX_CMPL_ERRORS_BUFFER_ERROR_NO_ERROR (UINT32_C(0x0) << 1)
+ /*
+ * Bad Format:
+ * BDs were not formatted correctly.
+ */
+ #define TX_CMPL_ERRORS_BUFFER_ERROR_BAD_FMT (UINT32_C(0x2) << 1)
+ #define TX_CMPL_ERRORS_BUFFER_ERROR_LAST \
+ TX_CMPL_ERRORS_BUFFER_ERROR_BAD_FMT
+ /*
+ * When this bit is '1', it indicates that the length of
+ * the packet was zero. No packet was transmitted.
+ */
+ #define TX_CMPL_ERRORS_ZERO_LENGTH_PKT UINT32_C(0x10)
+ /*
+ * When this bit is '1', it indicates that the packet
+ * was longer than the programmed limit in TDI. No
+ * packet was transmitted.
+ */
+ #define TX_CMPL_ERRORS_EXCESSIVE_BD_LENGTH UINT32_C(0x20)
+ /*
+ * When this bit is '1', it indicates that one or more of the
+ * BDs associated with this packet generated a PCI error.
+ * This probably means the address was not valid.
+ */
+ #define TX_CMPL_ERRORS_DMA_ERROR UINT32_C(0x40)
+ /*
+ * When this bit is '1', it indicates that the packet was longer
+ * than indicated by the hint. No packet was transmitted.
+ */
+ #define TX_CMPL_ERRORS_HINT_TOO_SHORT UINT32_C(0x80)
+ /*
+ * When this bit is '1', it indicates that the packet was
+ * dropped due to Poison TLP error on one or more of the
+ * TLPs in the PXP completion.
+ */
+ #define TX_CMPL_ERRORS_POISON_TLP_ERROR UINT32_C(0x100)
+ /* unused2 is 16 b */
+ uint16_t unused_1;
+ /* unused3 is 32 b */
+ uint32_t unused_2;
+} __attribute__((packed));
+
+/* rx_pkt_cmpl (size:128b/16B) */
+struct rx_pkt_cmpl {
+ uint16_t flags_type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define RX_PKT_CMPL_TYPE_MASK UINT32_C(0x3f)
+ #define RX_PKT_CMPL_TYPE_SFT 0
+ /*
+ * RX L2 completion:
+ * Completion of and L2 RX packet. Length = 32B
+ */
+ #define RX_PKT_CMPL_TYPE_RX_L2 UINT32_C(0x11)
+ #define RX_PKT_CMPL_TYPE_LAST RX_PKT_CMPL_TYPE_RX_L2
+ #define RX_PKT_CMPL_FLAGS_MASK UINT32_C(0xffc0)
+ #define RX_PKT_CMPL_FLAGS_SFT 6
+ /*
+ * When this bit is '1', it indicates a packet that has an
+ * error of some type. Type of error is indicated in
+ * error_flags.
+ */
+ #define RX_PKT_CMPL_FLAGS_ERROR UINT32_C(0x40)
+ /* This field indicates how the packet was placed in the buffer. */
+ #define RX_PKT_CMPL_FLAGS_PLACEMENT_MASK UINT32_C(0x380)
+ #define RX_PKT_CMPL_FLAGS_PLACEMENT_SFT 7
+ /*
+ * Normal:
+ * Packet was placed using normal algorithm.
+ */
+ #define RX_PKT_CMPL_FLAGS_PLACEMENT_NORMAL (UINT32_C(0x0) << 7)
+ /*
+ * Jumbo:
+ * Packet was placed using jumbo algorithm.
+ */
+ #define RX_PKT_CMPL_FLAGS_PLACEMENT_JUMBO (UINT32_C(0x1) << 7)
+ /*
+ * Header/Data Separation:
+ * Packet was placed using Header/Data separation algorithm.
+ * The separation location is indicated by the itype field.
+ */
+ #define RX_PKT_CMPL_FLAGS_PLACEMENT_HDS (UINT32_C(0x2) << 7)
+ #define RX_PKT_CMPL_FLAGS_PLACEMENT_LAST \
+ RX_PKT_CMPL_FLAGS_PLACEMENT_HDS
+ /* This bit is '1' if the RSS field in this completion is valid. */
+ #define RX_PKT_CMPL_FLAGS_RSS_VALID UINT32_C(0x400)
+ /* unused is 1 b */
+ #define RX_PKT_CMPL_FLAGS_UNUSED UINT32_C(0x800)
+ /*
+ * This value indicates what the inner packet determined for the
+ * packet was.
+ */
+ #define RX_PKT_CMPL_FLAGS_ITYPE_MASK UINT32_C(0xf000)
+ #define RX_PKT_CMPL_FLAGS_ITYPE_SFT 12
+ /*
+ * Not Known:
+ * Indicates that the packet type was not known.
+ */
+ #define RX_PKT_CMPL_FLAGS_ITYPE_NOT_KNOWN \
+ (UINT32_C(0x0) << 12)
+ /*
+ * IP Packet:
+ * Indicates that the packet was an IP packet, but further
+ * classification was not possible.
+ */
+ #define RX_PKT_CMPL_FLAGS_ITYPE_IP \
+ (UINT32_C(0x1) << 12)
+ /*
+ * TCP Packet:
+ * Indicates that the packet was IP and TCP.
+ * This indicates that the payload_offset field is valid.
+ */
+ #define RX_PKT_CMPL_FLAGS_ITYPE_TCP \
+ (UINT32_C(0x2) << 12)
+ /*
+ * UDP Packet:
+ * Indicates that the packet was IP and UDP.
+ * This indicates that the payload_offset field is valid.
+ */
+ #define RX_PKT_CMPL_FLAGS_ITYPE_UDP \
+ (UINT32_C(0x3) << 12)
+ /*
+ * FCoE Packet:
+ * Indicates that the packet was recognized as a FCoE.
+ * This also indicates that the payload_offset field is valid.
+ */
+ #define RX_PKT_CMPL_FLAGS_ITYPE_FCOE \
+ (UINT32_C(0x4) << 12)
+ /*
+ * RoCE Packet:
+ * Indicates that the packet was recognized as a RoCE.
+ * This also indicates that the payload_offset field is valid.
+ */
+ #define RX_PKT_CMPL_FLAGS_ITYPE_ROCE \
+ (UINT32_C(0x5) << 12)
+ /*
+ * ICMP Packet:
+ * Indicates that the packet was recognized as ICMP.
+ * This indicates that the payload_offset field is valid.
+ */
+ #define RX_PKT_CMPL_FLAGS_ITYPE_ICMP \
+ (UINT32_C(0x7) << 12)
+ /*
+ * PtP packet wo/timestamp:
+ * Indicates that the packet was recognized as a PtP
+ * packet.
+ */
+ #define RX_PKT_CMPL_FLAGS_ITYPE_PTP_WO_TIMESTAMP \
+ (UINT32_C(0x8) << 12)
+ /*
+ * PtP packet w/timestamp:
+ * Indicates that the packet was recognized as a PtP
+ * packet and that a timestamp was taken for the packet.
+ */
+ #define RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP \
+ (UINT32_C(0x9) << 12)
+ #define RX_PKT_CMPL_FLAGS_ITYPE_LAST \
+ RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP
+ /*
+ * This is the length of the data for the packet stored in the
+ * buffer(s) identified by the opaque value. This includes
+ * the packet BD and any associated buffer BDs. This does not include
+ * the the length of any data places in aggregation BDs.
+ */
+ uint16_t len;
+ /*
+ * This is a copy of the opaque field from the RX BD this completion
+ * corresponds to.
+ */
+ uint32_t opaque;
+ uint8_t agg_bufs_v1;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define RX_PKT_CMPL_V1 UINT32_C(0x1)
+ /*
+ * This value is the number of aggregation buffers that follow this
+ * entry in the completion ring that are a part of this packet.
+ * If the value is zero, then the packet is completely contained
+ * in the buffer space provided for the packet in the RX ring.
+ */
+ #define RX_PKT_CMPL_AGG_BUFS_MASK UINT32_C(0x3e)
+ #define RX_PKT_CMPL_AGG_BUFS_SFT 1
+ /* unused1 is 2 b */
+ #define RX_PKT_CMPL_UNUSED1_MASK UINT32_C(0xc0)
+ #define RX_PKT_CMPL_UNUSED1_SFT 6
+ /*
+ * This is the RSS hash type for the packet. The value is packed
+ * {tuple_extrac_op[1:0],rss_profile_id[4:0],tuple_extrac_op[2]}.
+ *
+ * The value of tuple_extrac_op provides the information about
+ * what fields the hash was computed on.
+ * * 0: The RSS hash was computed over source IP address,
+ * destination IP address, source port, and destination port of inner
+ * IP and TCP or UDP headers. Note: For non-tunneled packets,
+ * the packet headers are considered inner packet headers for the RSS
+ * hash computation purpose.
+ * * 1: The RSS hash was computed over source IP address and destination
+ * IP address of inner IP header. Note: For non-tunneled packets,
+ * the packet headers are considered inner packet headers for the RSS
+ * hash computation purpose.
+ * * 2: The RSS hash was computed over source IP address,
+ * destination IP address, source port, and destination port of
+ * IP and TCP or UDP headers of outer tunnel headers.
+ * Note: For non-tunneled packets, this value is not applicable.
+ * * 3: The RSS hash was computed over source IP address and
+ * destination IP address of IP header of outer tunnel headers.
+ * Note: For non-tunneled packets, this value is not applicable.
+ *
+ * Note that 4-tuples values listed above are applicable
+ * for layer 4 protocols supported and enabled for RSS in the hardware,
+ * HWRM firmware, and drivers. For example, if RSS hash is supported and
+ * enabled for TCP traffic only, then the values of tuple_extract_op
+ * corresponding to 4-tuples are only valid for TCP traffic.
+ */
+ uint8_t rss_hash_type;
+ /*
+ * This value indicates the offset in bytes from the beginning of the packet
+ * where the inner payload starts. This value is valid for TCP, UDP,
+ * FCoE, and RoCE packets.
+ *
+ * A value of zero indicates that header is 256B into the packet.
+ */
+ uint8_t payload_offset;
+ /* unused2 is 8 b */
+ uint8_t unused1;
+ /*
+ * This value is the RSS hash value calculated for the packet
+ * based on the mode bits and key value in the VNIC.
+ */
+ uint32_t rss_hash;
+} __attribute__((packed));
+
+/* rx_pkt_cmpl_hi (size:128b/16B) */
+struct rx_pkt_cmpl_hi {
+ uint32_t flags2;
+ /*
+ * This indicates that the ip checksum was calculated for the
+ * inner packet and that the ip_cs_error field indicates if there
+ * was an error.
+ */
+ #define RX_PKT_CMPL_FLAGS2_IP_CS_CALC UINT32_C(0x1)
+ /*
+ * This indicates that the TCP, UDP or ICMP checksum was
+ * calculated for the inner packet and that the l4_cs_error field
+ * indicates if there was an error.
+ */
+ #define RX_PKT_CMPL_FLAGS2_L4_CS_CALC UINT32_C(0x2)
+ /*
+ * This indicates that the ip checksum was calculated for the
+ * tunnel header and that the t_ip_cs_error field indicates if there
+ * was an error.
+ */
+ #define RX_PKT_CMPL_FLAGS2_T_IP_CS_CALC UINT32_C(0x4)
+ /*
+ * This indicates that the UDP checksum was
+ * calculated for the tunnel packet and that the t_l4_cs_error field
+ * indicates if there was an error.
+ */
+ #define RX_PKT_CMPL_FLAGS2_T_L4_CS_CALC UINT32_C(0x8)
+ /* This value indicates what format the metadata field is. */
+ #define RX_PKT_CMPL_FLAGS2_META_FORMAT_MASK UINT32_C(0xf0)
+ #define RX_PKT_CMPL_FLAGS2_META_FORMAT_SFT 4
+ /* No metadata informtaion. Value is zero. */
+ #define RX_PKT_CMPL_FLAGS2_META_FORMAT_NONE (UINT32_C(0x0) << 4)
+ /*
+ * The metadata field contains the VLAN tag and TPID value.
+ * - metadata[11:0] contains the vlan VID value.
+ * - metadata[12] contains the vlan DE value.
+ * - metadata[15:13] contains the vlan PRI value.
+ * - metadata[31:16] contains the vlan TPID value.
+ */
+ #define RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN (UINT32_C(0x1) << 4)
+ #define RX_PKT_CMPL_FLAGS2_META_FORMAT_LAST \
+ RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN
+ /*
+ * This field indicates the IP type for the inner-most IP header.
+ * A value of '0' indicates IPv4. A value of '1' indicates IPv6.
+ * This value is only valid if itype indicates a packet
+ * with an IP header.
+ */
+ #define RX_PKT_CMPL_FLAGS2_IP_TYPE UINT32_C(0x100)
+ /*
+ * This is data from the CFA block as indicated by the meta_format
+ * field.
+ */
+ uint32_t metadata;
+ /* When meta_format=1, this value is the VLAN VID. */
+ #define RX_PKT_CMPL_METADATA_VID_MASK UINT32_C(0xfff)
+ #define RX_PKT_CMPL_METADATA_VID_SFT 0
+ /* When meta_format=1, this value is the VLAN DE. */
+ #define RX_PKT_CMPL_METADATA_DE UINT32_C(0x1000)
+ /* When meta_format=1, this value is the VLAN PRI. */
+ #define RX_PKT_CMPL_METADATA_PRI_MASK UINT32_C(0xe000)
+ #define RX_PKT_CMPL_METADATA_PRI_SFT 13
+ /* When meta_format=1, this value is the VLAN TPID. */
+ #define RX_PKT_CMPL_METADATA_TPID_MASK UINT32_C(0xffff0000)
+ #define RX_PKT_CMPL_METADATA_TPID_SFT 16
+ uint16_t errors_v2;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define RX_PKT_CMPL_V2 \
+ UINT32_C(0x1)
+ #define RX_PKT_CMPL_ERRORS_MASK \
+ UINT32_C(0xfffe)
+ #define RX_PKT_CMPL_ERRORS_SFT 1
+ /*
+ * This error indicates that there was some sort of problem with
+ * the BDs for the packet that was found after part of the
+ * packet was already placed. The packet should be treated as
+ * invalid.
+ */
+ #define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_MASK \
+ UINT32_C(0xe)
+ #define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_SFT 1
+ /* No buffer error */
+ #define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_NO_BUFFER \
+ (UINT32_C(0x0) << 1)
+ /*
+ * Did Not Fit:
+ * Packet did not fit into packet buffer provided.
+ * For regular placement, this means the packet did not fit
+ * in the buffer provided. For HDS and jumbo placement, this
+ * means that the packet could not be placed into 7 physical
+ * buffers or less.
+ */
+ #define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_DID_NOT_FIT \
+ (UINT32_C(0x1) << 1)
+ /*
+ * Not On Chip:
+ * All BDs needed for the packet were not on-chip when
+ * the packet arrived.
+ */
+ #define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_NOT_ON_CHIP \
+ (UINT32_C(0x2) << 1)
+ /*
+ * Bad Format:
+ * BDs were not formatted correctly.
+ */
+ #define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_BAD_FORMAT \
+ (UINT32_C(0x3) << 1)
+ #define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_LAST \
+ RX_PKT_CMPL_ERRORS_BUFFER_ERROR_BAD_FORMAT
+ /*
+ * This indicates that there was an error in the IP header
+ * checksum.
+ */
+ #define RX_PKT_CMPL_ERRORS_IP_CS_ERROR \
+ UINT32_C(0x10)
+ /*
+ * This indicates that there was an error in the TCP, UDP
+ * or ICMP checksum.
+ */
+ #define RX_PKT_CMPL_ERRORS_L4_CS_ERROR \
+ UINT32_C(0x20)
+ /*
+ * This indicates that there was an error in the tunnel
+ * IP header checksum.
+ */
+ #define RX_PKT_CMPL_ERRORS_T_IP_CS_ERROR \
+ UINT32_C(0x40)
+ /*
+ * This indicates that there was an error in the tunnel
+ * UDP checksum.
+ */
+ #define RX_PKT_CMPL_ERRORS_T_L4_CS_ERROR \
+ UINT32_C(0x80)
+ /*
+ * This indicates that there was a CRC error on either an FCoE
+ * or RoCE packet. The itype indicates the packet type.
+ */
+ #define RX_PKT_CMPL_ERRORS_CRC_ERROR \
+ UINT32_C(0x100)
+ /*
+ * This indicates that there was an error in the tunnel
+ * portion of the packet when this
+ * field is non-zero.
+ */
+ #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_MASK \
+ UINT32_C(0xe00)
+ #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_SFT 9
+ /*
+ * No additional error occurred on the tunnel portion
+ * of the packet of the packet does not have a tunnel.
+ */
+ #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_NO_ERROR \
+ (UINT32_C(0x0) << 9)
+ /*
+ * Indicates that IP header version does not match
+ * expectation from L2 Ethertype for IPv4 and IPv6
+ * in the tunnel header.
+ */
+ #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_VERSION \
+ (UINT32_C(0x1) << 9)
+ /*
+ * Indicates that header length is out of range in the
+ * tunnel header. Valid for
+ * IPv4.
+ */
+ #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_HDR_LEN \
+ (UINT32_C(0x2) << 9)
+ /*
+ * Indicates that the physical packet is shorter than that
+ * claimed by the PPPoE header length for a tunnel PPPoE
+ * packet.
+ */
+ #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_TUNNEL_TOTAL_ERROR \
+ (UINT32_C(0x3) << 9)
+ /*
+ * Indicates that physical packet is shorter than that claimed
+ * by the tunnel l3 header length. Valid for IPv4, or IPv6
+ * tunnel packet packets.
+ */
+ #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_IP_TOTAL_ERROR \
+ (UINT32_C(0x4) << 9)
+ /*
+ * Indicates that the physical packet is shorter than that
+ * claimed by the tunnel UDP header length for a tunnel
+ * UDP packet that is not fragmented.
+ */
+ #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_UDP_TOTAL_ERROR \
+ (UINT32_C(0x5) << 9)
+ /*
+ * indicates that the IPv4 TTL or IPv6 hop limit check
+ * have failed (e.g. TTL = 0) in the tunnel header. Valid
+ * for IPv4, and IPv6.
+ */
+ #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_TTL \
+ (UINT32_C(0x6) << 9)
+ #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_LAST \
+ RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_TTL
+ /*
+ * This indicates that there was an error in the inner
+ * portion of the packet when this
+ * field is non-zero.
+ */
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_MASK \
+ UINT32_C(0xf000)
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_SFT 12
+ /*
+ * No additional error occurred on the tunnel portion
+ * of the packet of the packet does not have a tunnel.
+ */
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_NO_ERROR \
+ (UINT32_C(0x0) << 12)
+ /*
+ * Indicates that IP header version does not match
+ * expectation from L2 Ethertype for IPv4 and IPv6 or that
+ * option other than VFT was parsed on
+ * FCoE packet.
+ */
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_VERSION \
+ (UINT32_C(0x1) << 12)
+ /*
+ * indicates that header length is out of range. Valid for
+ * IPv4 and RoCE
+ */
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_HDR_LEN \
+ (UINT32_C(0x2) << 12)
+ /*
+ * indicates that the IPv4 TTL or IPv6 hop limit check
+ * have failed (e.g. TTL = 0). Valid for IPv4, and IPv6
+ */
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_TTL \
+ (UINT32_C(0x3) << 12)
+ /*
+ * Indicates that physical packet is shorter than that
+ * claimed by the l3 header length. Valid for IPv4,
+ * IPv6 packet or RoCE packets.
+ */
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_IP_TOTAL_ERROR \
+ (UINT32_C(0x4) << 12)
+ /*
+ * Indicates that the physical packet is shorter than that
+ * claimed by the UDP header length for a UDP packet that is
+ * not fragmented.
+ */
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_UDP_TOTAL_ERROR \
+ (UINT32_C(0x5) << 12)
+ /*
+ * Indicates that TCP header length > IP payload. Valid for
+ * TCP packets only.
+ */
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN \
+ (UINT32_C(0x6) << 12)
+ /* Indicates that TCP header length < 5. Valid for TCP. */
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN_TOO_SMALL \
+ (UINT32_C(0x7) << 12)
+ /*
+ * Indicates that TCP option headers result in a TCP header
+ * size that does not match data offset in TCP header. Valid
+ * for TCP.
+ */
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN \
+ (UINT32_C(0x8) << 12)
+ #define RX_PKT_CMPL_ERRORS_PKT_ERROR_LAST \
+ RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN
+ /*
+ * This field identifies the CFA action rule that was used for this
+ * packet.
+ */
+ uint16_t cfa_code;
+ uint32_t reorder;
+ /*
+ * This value holds the reordering sequence number for the packet.
+ * If the reordering sequence is not valid, then this value is zero.
+ * The reordering domain for the packet is in the bottom 8 to 10b of
+ * the rss_hash value. The bottom 20b of this value contain the
+ * ordering domain value for the packet.
+ */
+ #define RX_PKT_CMPL_REORDER_MASK UINT32_C(0xffffff)
+ #define RX_PKT_CMPL_REORDER_SFT 0
+} __attribute__((packed));
+
+/* rx_tpa_start_cmpl (size:128b/16B) */
+struct rx_tpa_start_cmpl {
+ uint16_t flags_type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define RX_TPA_START_CMPL_TYPE_MASK UINT32_C(0x3f)
+ #define RX_TPA_START_CMPL_TYPE_SFT 0
+ /*
+ * RX L2 TPA Start Completion:
+ * Completion at the beginning of a TPA operation.
+ * Length = 32B
+ */
+ #define RX_TPA_START_CMPL_TYPE_RX_TPA_START UINT32_C(0x13)
+ #define RX_TPA_START_CMPL_TYPE_LAST \
+ RX_TPA_START_CMPL_TYPE_RX_TPA_START
+ #define RX_TPA_START_CMPL_FLAGS_MASK UINT32_C(0xffc0)
+ #define RX_TPA_START_CMPL_FLAGS_SFT 6
+ /* This bit will always be '0' for TPA start completions. */
+ #define RX_TPA_START_CMPL_FLAGS_ERROR UINT32_C(0x40)
+ /* This field indicates how the packet was placed in the buffer. */
+ #define RX_TPA_START_CMPL_FLAGS_PLACEMENT_MASK UINT32_C(0x380)
+ #define RX_TPA_START_CMPL_FLAGS_PLACEMENT_SFT 7
+ /*
+ * Jumbo:
+ * TPA Packet was placed using jumbo algorithm. This means
+ * that the first buffer will be filled with data before
+ * moving to aggregation buffers. Each aggregation buffer
+ * will be filled before moving to the next aggregation
+ * buffer.
+ */
+ #define RX_TPA_START_CMPL_FLAGS_PLACEMENT_JUMBO \
+ (UINT32_C(0x1) << 7)
+ /*
+ * Header/Data Separation:
+ * Packet was placed using Header/Data separation algorithm.
+ * The separation location is indicated by the itype field.
+ */
+ #define RX_TPA_START_CMPL_FLAGS_PLACEMENT_HDS \
+ (UINT32_C(0x2) << 7)
+ /*
+ * GRO/Jumbo:
+ * Packet will be placed using GRO/Jumbo where the first
+ * packet is filled with data. Subsequent packets will be
+ * placed such that any one packet does not span two
+ * aggregation buffers unless it starts at the beginning of
+ * an aggregation buffer.
+ */
+ #define RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_JUMBO \
+ (UINT32_C(0x5) << 7)
+ /*
+ * GRO/Header-Data Separation:
+ * Packet will be placed using GRO/HDS where the header
+ * is in the first packet.
+ * Payload of each packet will be
+ * placed such that any one packet does not span two
+ * aggregation buffers unless it starts at the beginning of
+ * an aggregation buffer.
+ */
+ #define RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_HDS \
+ (UINT32_C(0x6) << 7)
+ #define RX_TPA_START_CMPL_FLAGS_PLACEMENT_LAST \
+ RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_HDS
+ /* This bit is '1' if the RSS field in this completion is valid. */
+ #define RX_TPA_START_CMPL_FLAGS_RSS_VALID UINT32_C(0x400)
+ /* unused is 1 b */
+ #define RX_TPA_START_CMPL_FLAGS_UNUSED UINT32_C(0x800)
+ /*
+ * This value indicates what the inner packet determined for the
+ * packet was.
+ */
+ #define RX_TPA_START_CMPL_FLAGS_ITYPE_MASK UINT32_C(0xf000)
+ #define RX_TPA_START_CMPL_FLAGS_ITYPE_SFT 12
+ /*
+ * TCP Packet:
+ * Indicates that the packet was IP and TCP.
+ */
+ #define RX_TPA_START_CMPL_FLAGS_ITYPE_TCP \
+ (UINT32_C(0x2) << 12)
+ #define RX_TPA_START_CMPL_FLAGS_ITYPE_LAST \
+ RX_TPA_START_CMPL_FLAGS_ITYPE_TCP
+ /*
+ * This value indicates the amount of packet data written to the
+ * buffer the opaque field in this completion corresponds to.
+ */
+ uint16_t len;
+ /*
+ * This is a copy of the opaque field from the RX BD this completion
+ * corresponds to.
+ */
+ uint32_t opaque;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ uint8_t v1;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define RX_TPA_START_CMPL_V1 UINT32_C(0x1)
+ #define RX_TPA_START_CMPL_LAST RX_TPA_START_CMPL_V1
+ /*
+ * This is the RSS hash type for the packet. The value is packed
+ * {tuple_extrac_op[1:0],rss_profile_id[4:0],tuple_extrac_op[2]}.
+ *
+ * The value of tuple_extrac_op provides the information about
+ * what fields the hash was computed on.
+ * * 0: The RSS hash was computed over source IP address,
+ * destination IP address, source port, and destination port of inner
+ * IP and TCP or UDP headers. Note: For non-tunneled packets,
+ * the packet headers are considered inner packet headers for the RSS
+ * hash computation purpose.
+ * * 1: The RSS hash was computed over source IP address and destination
+ * IP address of inner IP header. Note: For non-tunneled packets,
+ * the packet headers are considered inner packet headers for the RSS
+ * hash computation purpose.
+ * * 2: The RSS hash was computed over source IP address,
+ * destination IP address, source port, and destination port of
+ * IP and TCP or UDP headers of outer tunnel headers.
+ * Note: For non-tunneled packets, this value is not applicable.
+ * * 3: The RSS hash was computed over source IP address and
+ * destination IP address of IP header of outer tunnel headers.
+ * Note: For non-tunneled packets, this value is not applicable.
+ *
+ * Note that 4-tuples values listed above are applicable
+ * for layer 4 protocols supported and enabled for RSS in the hardware,
+ * HWRM firmware, and drivers. For example, if RSS hash is supported and
+ * enabled for TCP traffic only, then the values of tuple_extract_op
+ * corresponding to 4-tuples are only valid for TCP traffic.
+ */
+ uint8_t rss_hash_type;
+ /*
+ * This is the aggregation ID that the completion is associated
+ * with. Use this number to correlate the TPA start completion
+ * with the TPA end completion.
+ */
+ uint16_t agg_id;
+ /* unused2 is 9 b */
+ #define RX_TPA_START_CMPL_UNUSED2_MASK UINT32_C(0x1ff)
+ #define RX_TPA_START_CMPL_UNUSED2_SFT 0
+ /*
+ * This is the aggregation ID that the completion is associated
+ * with. Use this number to correlate the TPA start completion
+ * with the TPA end completion.
+ */
+ #define RX_TPA_START_CMPL_AGG_ID_MASK UINT32_C(0xfe00)
+ #define RX_TPA_START_CMPL_AGG_ID_SFT 9
+ /*
+ * This value is the RSS hash value calculated for the packet
+ * based on the mode bits and key value in the VNIC.
+ */
+ uint32_t rss_hash;
+} __attribute__((packed));
+
+/* rx_tpa_start_cmpl_hi (size:128b/16B) */
+struct rx_tpa_start_cmpl_hi {
+ uint32_t flags2;
+ /*
+ * This indicates that the ip checksum was calculated for the
+ * inner packet and that the sum passed for all segments
+ * included in the aggregation.
+ */
+ #define RX_TPA_START_CMPL_FLAGS2_IP_CS_CALC UINT32_C(0x1)
+ /*
+ * This indicates that the TCP, UDP or ICMP checksum was
+ * calculated for the inner packet and that the sum passed
+ * for all segments included in the aggregation.
+ */
+ #define RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC UINT32_C(0x2)
+ /*
+ * This indicates that the ip checksum was calculated for the
+ * tunnel header and that the sum passed for all segments
+ * included in the aggregation.
+ */
+ #define RX_TPA_START_CMPL_FLAGS2_T_IP_CS_CALC UINT32_C(0x4)
+ /*
+ * This indicates that the UDP checksum was
+ * calculated for the tunnel packet and that the sum passed for
+ * all segments included in the aggregation.
+ */
+ #define RX_TPA_START_CMPL_FLAGS2_T_L4_CS_CALC UINT32_C(0x8)
+ /* This value indicates what format the metadata field is. */
+ #define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_MASK UINT32_C(0xf0)
+ #define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_SFT 4
+ /* No metadata informtaion. Value is zero. */
+ #define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_NONE \
+ (UINT32_C(0x0) << 4)
+ /*
+ * The metadata field contains the VLAN tag and TPID value.
+ * - metadata[11:0] contains the vlan VID value.
+ * - metadata[12] contains the vlan DE value.
+ * - metadata[15:13] contains the vlan PRI value.
+ * - metadata[31:16] contains the vlan TPID value.
+ */
+ #define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN \
+ (UINT32_C(0x1) << 4)
+ #define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_LAST \
+ RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN
+ /*
+ * This field indicates the IP type for the inner-most IP header.
+ * A value of '0' indicates IPv4. A value of '1' indicates IPv6.
+ */
+ #define RX_TPA_START_CMPL_FLAGS2_IP_TYPE UINT32_C(0x100)
+ /*
+ * This is data from the CFA block as indicated by the meta_format
+ * field.
+ */
+ uint32_t metadata;
+ /* When meta_format=1, this value is the VLAN VID. */
+ #define RX_TPA_START_CMPL_METADATA_VID_MASK UINT32_C(0xfff)
+ #define RX_TPA_START_CMPL_METADATA_VID_SFT 0
+ /* When meta_format=1, this value is the VLAN DE. */
+ #define RX_TPA_START_CMPL_METADATA_DE UINT32_C(0x1000)
+ /* When meta_format=1, this value is the VLAN PRI. */
+ #define RX_TPA_START_CMPL_METADATA_PRI_MASK UINT32_C(0xe000)
+ #define RX_TPA_START_CMPL_METADATA_PRI_SFT 13
+ /* When meta_format=1, this value is the VLAN TPID. */
+ #define RX_TPA_START_CMPL_METADATA_TPID_MASK UINT32_C(0xffff0000)
+ #define RX_TPA_START_CMPL_METADATA_TPID_SFT 16
+ uint16_t v2;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define RX_TPA_START_CMPL_V2 UINT32_C(0x1)
+ /*
+ * This field identifies the CFA action rule that was used for this
+ * packet.
+ */
+ uint16_t cfa_code;
+ /*
+ * This is the size in bytes of the inner most L4 header.
+ * This can be subtracted from the payload_offset to determine
+ * the start of the inner most L4 header.
+ */
+ uint32_t inner_l4_size_inner_l3_offset_inner_l2_offset_outer_l3_offset;
+ /*
+ * This is the offset from the beginning of the packet in bytes for
+ * the outer L3 header. If there is no outer L3 header, then this
+ * value is zero.
+ */
+ #define RX_TPA_START_CMPL_OUTER_L3_OFFSET_MASK UINT32_C(0x1ff)
+ #define RX_TPA_START_CMPL_OUTER_L3_OFFSET_SFT 0
+ /*
+ * This is the offset from the beginning of the packet in bytes for
+ * the inner most L2 header.
+ */
+ #define RX_TPA_START_CMPL_INNER_L2_OFFSET_MASK UINT32_C(0x3fe00)
+ #define RX_TPA_START_CMPL_INNER_L2_OFFSET_SFT 9
+ /*
+ * This is the offset from the beginning of the packet in bytes for
+ * the inner most L3 header.
+ */
+ #define RX_TPA_START_CMPL_INNER_L3_OFFSET_MASK UINT32_C(0x7fc0000)
+ #define RX_TPA_START_CMPL_INNER_L3_OFFSET_SFT 18
+ /*
+ * This is the size in bytes of the inner most L4 header.
+ * This can be subtracted from the payload_offset to determine
+ * the start of the inner most L4 header.
+ */
+ #define RX_TPA_START_CMPL_INNER_L4_SIZE_MASK UINT32_C(0xf8000000)
+ #define RX_TPA_START_CMPL_INNER_L4_SIZE_SFT 27
+} __attribute__((packed));
+
+/* rx_tpa_end_cmpl (size:128b/16B) */
+struct rx_tpa_end_cmpl {
+ uint16_t flags_type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define RX_TPA_END_CMPL_TYPE_MASK UINT32_C(0x3f)
+ #define RX_TPA_END_CMPL_TYPE_SFT 0
+ /*
+ * RX L2 TPA End Completion:
+ * Completion at the end of a TPA operation.
+ * Length = 32B
+ */
+ #define RX_TPA_END_CMPL_TYPE_RX_TPA_END UINT32_C(0x15)
+ #define RX_TPA_END_CMPL_TYPE_LAST \
+ RX_TPA_END_CMPL_TYPE_RX_TPA_END
+ #define RX_TPA_END_CMPL_FLAGS_MASK UINT32_C(0xffc0)
+ #define RX_TPA_END_CMPL_FLAGS_SFT 6
+ /*
+ * When this bit is '1', it indicates a packet that has an
+ * error of some type. Type of error is indicated in
+ * error_flags.
+ */
+ #define RX_TPA_END_CMPL_FLAGS_ERROR UINT32_C(0x40)
+ /* This field indicates how the packet was placed in the buffer. */
+ #define RX_TPA_END_CMPL_FLAGS_PLACEMENT_MASK UINT32_C(0x380)
+ #define RX_TPA_END_CMPL_FLAGS_PLACEMENT_SFT 7
+ /*
+ * Jumbo:
+ * TPA Packet was placed using jumbo algorithm. This means
+ * that the first buffer will be filled with data before
+ * moving to aggregation buffers. Each aggregation buffer
+ * will be filled before moving to the next aggregation
+ * buffer.
+ */
+ #define RX_TPA_END_CMPL_FLAGS_PLACEMENT_JUMBO \
+ (UINT32_C(0x1) << 7)
+ /*
+ * Header/Data Separation:
+ * Packet was placed using Header/Data separation algorithm.
+ * The separation location is indicated by the itype field.
+ */
+ #define RX_TPA_END_CMPL_FLAGS_PLACEMENT_HDS \
+ (UINT32_C(0x2) << 7)
+ /*
+ * GRO/Jumbo:
+ * Packet will be placed using GRO/Jumbo where the first
+ * packet is filled with data. Subsequent packets will be
+ * placed such that any one packet does not span two
+ * aggregation buffers unless it starts at the beginning of
+ * an aggregation buffer.
+ */
+ #define RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_JUMBO \
+ (UINT32_C(0x5) << 7)
+ /*
+ * GRO/Header-Data Separation:
+ * Packet will be placed using GRO/HDS where the header
+ * is in the first packet.
+ * Payload of each packet will be
+ * placed such that any one packet does not span two
+ * aggregation buffers unless it starts at the beginning of
+ * an aggregation buffer.
+ */
+ #define RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_HDS \
+ (UINT32_C(0x6) << 7)
+ #define RX_TPA_END_CMPL_FLAGS_PLACEMENT_LAST \
+ RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_HDS
+ /* unused is 2 b */
+ #define RX_TPA_END_CMPL_FLAGS_UNUSED_MASK UINT32_C(0xc00)
+ #define RX_TPA_END_CMPL_FLAGS_UNUSED_SFT 10
+ /*
+ * This value indicates what the inner packet determined for the
+ * packet was.
+ * - 2 TCP Packet
+ * Indicates that the packet was IP and TCP. This indicates
+ * that the ip_cs field is valid and that the tcp_udp_cs
+ * field is valid and contains the TCP checksum.
+ * This also indicates that the payload_offset field is valid.
+ */
+ #define RX_TPA_END_CMPL_FLAGS_ITYPE_MASK UINT32_C(0xf000)
+ #define RX_TPA_END_CMPL_FLAGS_ITYPE_SFT 12
+ /*
+ * This value is zero for TPA End completions.
+ * There is no data in the buffer that corresponds to the opaque
+ * value in this completion.
+ */
+ uint16_t len;
+ /*
+ * This is a copy of the opaque field from the RX BD this completion
+ * corresponds to.
+ */
+ uint32_t opaque;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ uint8_t agg_bufs_v1;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define RX_TPA_END_CMPL_V1 UINT32_C(0x1)
+ /*
+ * This value is the number of aggregation buffers that follow this
+ * entry in the completion ring that are a part of this aggregation
+ * packet.
+ * If the value is zero, then the packet is completely contained
+ * in the buffer space provided in the aggregation start completion.
+ */
+ #define RX_TPA_END_CMPL_AGG_BUFS_MASK UINT32_C(0x7e)
+ #define RX_TPA_END_CMPL_AGG_BUFS_SFT 1
+ /* This value is the number of segments in the TPA operation. */
+ uint8_t tpa_segs;
+ /*
+ * This value indicates the offset in bytes from the beginning of the packet
+ * where the inner payload starts. This value is valid for TCP, UDP,
+ * FCoE, and RoCE packets.
+ *
+ * A value of zero indicates an offset of 256 bytes.
+ */
+ uint8_t payload_offset;
+ uint8_t agg_id;
+ /* unused2 is 1 b */
+ #define RX_TPA_END_CMPL_UNUSED2 UINT32_C(0x1)
+ /*
+ * This is the aggregation ID that the completion is associated
+ * with. Use this number to correlate the TPA start completion
+ * with the TPA end completion.
+ */
+ #define RX_TPA_END_CMPL_AGG_ID_MASK UINT32_C(0xfe)
+ #define RX_TPA_END_CMPL_AGG_ID_SFT 1
+ /*
+ * For non-GRO packets, this value is the
+ * timestamp delta between earliest and latest timestamp values for
+ * TPA packet. If packets were not time stamped, then delta will be
+ * zero.
+ *
+ * For GRO packets, this field is zero except for the following
+ * sub-fields.
+ * - tsdelta[31]
+ * Timestamp present indication. When '0', no Timestamp
+ * option is in the packet. When '1', then a Timestamp
+ * option is present in the packet.
+ */
+ uint32_t tsdelta;
+} __attribute__((packed));
+
+/* rx_tpa_end_cmpl_hi (size:128b/16B) */
+struct rx_tpa_end_cmpl_hi {
+ /*
+ * This value is the number of duplicate ACKs that have been
+ * received as part of the TPA operation.
+ */
+ uint32_t tpa_dup_acks;
+ /*
+ * This value is the number of duplicate ACKs that have been
+ * received as part of the TPA operation.
+ */
+ #define RX_TPA_END_CMPL_TPA_DUP_ACKS_MASK UINT32_C(0xf)
+ #define RX_TPA_END_CMPL_TPA_DUP_ACKS_SFT 0
+ /*
+ * This value is the valid when TPA completion is active. It
+ * indicates the length of the longest segment of the TPA operation
+ * for LRO mode and the length of the first segment in GRO mode.
+ *
+ * This value may be used by GRO software to re-construct the original
+ * packet stream from the TPA packet. This is the length of all
+ * but the last segment for GRO. In LRO mode this value may be used
+ * to indicate MSS size to the stack.
+ */
+ uint16_t tpa_seg_len;
+ /* unused4 is 16 b */
+ uint16_t unused3;
+ uint16_t errors_v2;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define RX_TPA_END_CMPL_V2 UINT32_C(0x1)
+ #define RX_TPA_END_CMPL_ERRORS_MASK UINT32_C(0xfffe)
+ #define RX_TPA_END_CMPL_ERRORS_SFT 1
+ /*
+ * This error indicates that there was some sort of problem with
+ * the BDs for the packet that was found after part of the
+ * packet was already placed. The packet should be treated as
+ * invalid.
+ */
+ #define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_MASK UINT32_C(0xe)
+ #define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_SFT 1
+ /*
+ * This error occurs when there is a fatal HW problem in
+ * the chip only. It indicates that there were not
+ * BDs on chip but that there was adequate reservation.
+ * provided by the TPA block.
+ */
+ #define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_NOT_ON_CHIP \
+ (UINT32_C(0x2) << 1)
+ /*
+ * This error occurs when TPA block was not configured to
+ * reserve adequate BDs for TPA operations on this RX
+ * ring. All data for the TPA operation was not placed.
+ *
+ * This error can also be generated when the number of
+ * segments is not programmed correctly in TPA and the
+ * 33 total aggregation buffers allowed for the TPA
+ * operation has been exceeded.
+ */
+ #define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_RSV_ERROR \
+ (UINT32_C(0x4) << 1)
+ #define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_LAST \
+ RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_RSV_ERROR
+ /* unused5 is 16 b */
+ uint16_t unused_4;
+ /*
+ * This is the opaque value that was completed for the TPA start
+ * completion that corresponds to this TPA end completion.
+ */
+ uint32_t start_opaque;
+} __attribute__((packed));
+
+/* rx_abuf_cmpl (size:128b/16B) */
+struct rx_abuf_cmpl {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define RX_ABUF_CMPL_TYPE_MASK UINT32_C(0x3f)
+ #define RX_ABUF_CMPL_TYPE_SFT 0
+ /*
+ * RX Aggregation Buffer completion :
+ * Completion of an L2 aggregation buffer in support of
+ * TPA, HDS, or Jumbo packet completion. Length = 16B
+ */
+ #define RX_ABUF_CMPL_TYPE_RX_AGG UINT32_C(0x12)
+ #define RX_ABUF_CMPL_TYPE_LAST RX_ABUF_CMPL_TYPE_RX_AGG
+ /*
+ * This is the length of the data for the packet stored in this
+ * aggregation buffer identified by the opaque value. This does not
+ * include the length of any
+ * data placed in other aggregation BDs or in the packet or buffer
+ * BDs. This length does not include any space added due to
+ * hdr_offset register during HDS placement mode.
+ */
+ uint16_t len;
+ /*
+ * This is a copy of the opaque field from the RX BD this aggregation
+ * buffer corresponds to.
+ */
+ uint32_t opaque;
+ uint32_t v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define RX_ABUF_CMPL_V UINT32_C(0x1)
+ /* unused3 is 32 b */
+ uint32_t unused_2;
+} __attribute__((packed));
+
+/* eject_cmpl (size:128b/16B) */
+struct eject_cmpl {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define EJECT_CMPL_TYPE_MASK UINT32_C(0x3f)
+ #define EJECT_CMPL_TYPE_SFT 0
+ /*
+ * Statistics Ejection Completion:
+ * Completion of statistics data ejection buffer.
+ * Length = 16B
+ */
+ #define EJECT_CMPL_TYPE_STAT_EJECT UINT32_C(0x1a)
+ #define EJECT_CMPL_TYPE_LAST EJECT_CMPL_TYPE_STAT_EJECT
+ /*
+ * This is the length of the statistics data stored in this
+ * buffer.
+ */
+ uint16_t len;
+ /*
+ * This is a copy of the opaque field from the RX BD this ejection
+ * buffer corresponds to.
+ */
+ uint32_t opaque;
+ uint32_t v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define EJECT_CMPL_V UINT32_C(0x1)
+ /* unused3 is 32 b */
+ uint32_t unused_2;
+} __attribute__((packed));
+
+/* hwrm_cmpl (size:128b/16B) */
+struct hwrm_cmpl {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_CMPL_TYPE_MASK UINT32_C(0x3f)
+ #define HWRM_CMPL_TYPE_SFT 0
+ /*
+ * HWRM Command Completion:
+ * Completion of an HWRM command.
+ */
+ #define HWRM_CMPL_TYPE_HWRM_DONE UINT32_C(0x20)
+ #define HWRM_CMPL_TYPE_LAST HWRM_CMPL_TYPE_HWRM_DONE
+ /* This is the sequence_id of the HWRM command that has completed. */
+ uint16_t sequence_id;
+ /* unused2 is 32 b */
+ uint32_t unused_1;
+ uint32_t v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_CMPL_V UINT32_C(0x1)
+ /* unused4 is 32 b */
+ uint32_t unused_3;
+} __attribute__((packed));
+
+/* hwrm_fwd_req_cmpl (size:128b/16B) */
+struct hwrm_fwd_req_cmpl {
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ uint16_t req_len_type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_FWD_REQ_CMPL_TYPE_MASK UINT32_C(0x3f)
+ #define HWRM_FWD_REQ_CMPL_TYPE_SFT 0
+ /* Forwarded HWRM Request */
+ #define HWRM_FWD_REQ_CMPL_TYPE_HWRM_FWD_REQ UINT32_C(0x22)
+ #define HWRM_FWD_REQ_CMPL_TYPE_LAST \
+ HWRM_FWD_REQ_CMPL_TYPE_HWRM_FWD_REQ
+ /* Length of forwarded request in bytes. */
+ #define HWRM_FWD_REQ_CMPL_REQ_LEN_MASK UINT32_C(0xffc0)
+ #define HWRM_FWD_REQ_CMPL_REQ_LEN_SFT 6
+ /*
+ * Source ID of this request.
+ * Typically used in forwarding requests and responses.
+ * 0x0 - 0xFFF8 - Used for function ids
+ * 0xFFF8 - 0xFFFE - Reserved for internal processors
+ * 0xFFFF - HWRM
+ */
+ uint16_t source_id;
+ /* unused1 is 32 b */
+ uint32_t unused0;
+ /* Address of forwarded request. */
+ uint32_t req_buf_addr_v[2];
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_FWD_REQ_CMPL_V UINT32_C(0x1)
+ /* Address of forwarded request. */
+ #define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_MASK UINT32_C(0xfffffffe)
+ #define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_SFT 1
+} __attribute__((packed));
+
+/* hwrm_fwd_resp_cmpl (size:128b/16B) */
+struct hwrm_fwd_resp_cmpl {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_FWD_RESP_CMPL_TYPE_MASK UINT32_C(0x3f)
+ #define HWRM_FWD_RESP_CMPL_TYPE_SFT 0
+ /* Forwarded HWRM Response */
+ #define HWRM_FWD_RESP_CMPL_TYPE_HWRM_FWD_RESP UINT32_C(0x24)
+ #define HWRM_FWD_RESP_CMPL_TYPE_LAST \
+ HWRM_FWD_RESP_CMPL_TYPE_HWRM_FWD_RESP
+ /*
+ * Source ID of this response.
+ * Typically used in forwarding requests and responses.
+ * 0x0 - 0xFFF8 - Used for function ids
+ * 0xFFF8 - 0xFFFE - Reserved for internal processors
+ * 0xFFFF - HWRM
+ */
+ uint16_t source_id;
+ /* Length of forwarded response in bytes. */
+ uint16_t resp_len;
+ /* unused2 is 16 b */
+ uint16_t unused_1;
+ /* Address of forwarded request. */
+ uint32_t resp_buf_addr_v[2];
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_FWD_RESP_CMPL_V UINT32_C(0x1)
+ /* Address of forwarded request. */
+ #define HWRM_FWD_RESP_CMPL_RESP_BUF_ADDR_MASK UINT32_C(0xfffffffe)
+ #define HWRM_FWD_RESP_CMPL_RESP_BUF_ADDR_SFT 1
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl (size:128b/16B) */
+struct hwrm_async_event_cmpl {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_TYPE_MASK UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Link status changed */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE \
+ UINT32_C(0x0)
+ /* Link MTU changed */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE \
+ UINT32_C(0x1)
+ /* Link speed changed */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE \
+ UINT32_C(0x2)
+ /* DCB Configuration changed */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE \
+ UINT32_C(0x3)
+ /* Port connection not allowed */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED \
+ UINT32_C(0x4)
+ /* Link speed configuration was not allowed */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED \
+ UINT32_C(0x5)
+ /* Link speed configuration change */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE \
+ UINT32_C(0x6)
+ /* Port PHY configuration change */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE \
+ UINT32_C(0x7)
+ /* Function driver unloaded */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD \
+ UINT32_C(0x10)
+ /* Function driver loaded */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD \
+ UINT32_C(0x11)
+ /* Function FLR related processing has completed */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_FLR_PROC_CMPLT \
+ UINT32_C(0x12)
+ /* PF driver unloaded */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD \
+ UINT32_C(0x20)
+ /* PF driver loaded */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_LOAD \
+ UINT32_C(0x21)
+ /* VF Function Level Reset (FLR) */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR \
+ UINT32_C(0x30)
+ /* VF MAC Address Change */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE \
+ UINT32_C(0x31)
+ /* PF-VF communication channel status change. */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE \
+ UINT32_C(0x32)
+ /* VF Configuration Change */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE \
+ UINT32_C(0x33)
+ /* LLFC/PFC Configuration Change */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LLFC_PFC_CHANGE \
+ UINT32_C(0x34)
+ /* Default VNIC Configuration Change */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DEFAULT_VNIC_CHANGE \
+ UINT32_C(0x35)
+ /* HWRM Error */
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_HWRM_ERROR \
+ UINT32_C(0xff)
+ #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_EVENT_ID_HWRM_ERROR
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_V UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_OPAQUE_MASK UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_link_status_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_link_status_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Link status changed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_ID_LINK_STATUS_CHANGE \
+ UINT32_C(0x0)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_ID_LINK_STATUS_CHANGE
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* Indicates link status change */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_LINK_CHANGE \
+ UINT32_C(0x1)
+ /*
+ * If this bit set to 0, then it indicates that the link
+ * was up and it went down.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_LINK_CHANGE_DOWN \
+ UINT32_C(0x0)
+ /*
+ * If this bit is set to 1, then it indicates that the link
+ * was down and it went up.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_LINK_CHANGE_UP \
+ UINT32_C(0x1)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_LINK_CHANGE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_LINK_CHANGE_UP
+ /* Indicates the physical port this link status change occur */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_PORT_MASK \
+ UINT32_C(0xe)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_PORT_SFT \
+ 1
+ /* PORT ID */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_PORT_ID_MASK \
+ UINT32_C(0xffff0)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_PORT_ID_SFT \
+ 4
+ /* Indicates the physical function this event occured on. */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_PF_ID_MASK \
+ UINT32_C(0xff00000)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_STATUS_CHANGE_EVENT_DATA1_PF_ID_SFT \
+ 20
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_link_mtu_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_link_mtu_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Link MTU changed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_EVENT_ID_LINK_MTU_CHANGE \
+ UINT32_C(0x1)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_EVENT_ID_LINK_MTU_CHANGE
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_V UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* The new MTU of the link in bytes. */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_EVENT_DATA1_NEW_MTU_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_MTU_CHANGE_EVENT_DATA1_NEW_MTU_SFT 0
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_link_speed_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_link_speed_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Link speed changed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_ID_LINK_SPEED_CHANGE \
+ UINT32_C(0x2)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_ID_LINK_SPEED_CHANGE
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /*
+ * When this bit is '1', the link was forced to the
+ * force_link_speed value.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_FORCE \
+ UINT32_C(0x1)
+ /* The new link speed in 100 Mbps units. */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_MASK \
+ UINT32_C(0xfffe)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_SFT \
+ 1
+ /* 100Mb link speed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_100MB \
+ (UINT32_C(0x1) << 1)
+ /* 1Gb link speed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_1GB \
+ (UINT32_C(0xa) << 1)
+ /* 2Gb link speed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_2GB \
+ (UINT32_C(0x14) << 1)
+ /* 25Gb link speed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_2_5GB \
+ (UINT32_C(0x19) << 1)
+ /* 10Gb link speed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_10GB \
+ (UINT32_C(0x64) << 1)
+ /* 20Mb link speed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_20GB \
+ (UINT32_C(0xc8) << 1)
+ /* 25Gb link speed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_25GB \
+ (UINT32_C(0xfa) << 1)
+ /* 40Gb link speed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_40GB \
+ (UINT32_C(0x190) << 1)
+ /* 50Gb link speed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_50GB \
+ (UINT32_C(0x1f4) << 1)
+ /* 100Gb link speed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_100GB \
+ (UINT32_C(0x3e8) << 1)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_NEW_LINK_SPEED_100MBPS_100GB
+ /* PORT ID */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_PORT_ID_MASK \
+ UINT32_C(0xffff0000)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CHANGE_EVENT_DATA1_PORT_ID_SFT \
+ 16
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_dcb_config_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_dcb_config_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* DCB Configuration changed */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_ID_DCB_CONFIG_CHANGE \
+ UINT32_C(0x3)
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_ID_DCB_CONFIG_CHANGE
+ /* Event specific data */
+ uint32_t event_data2;
+ /* ETS configuration change */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA2_ETS \
+ UINT32_C(0x1)
+ /* PFC configuration change */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA2_PFC \
+ UINT32_C(0x2)
+ /* APP configuration change */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA2_APP \
+ UINT32_C(0x4)
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* PORT ID */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_PORT_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_PORT_ID_SFT \
+ 0
+ /* Priority recommended for RoCE traffic */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_RECOMMEND_ROCE_PRIORITY_MASK \
+ UINT32_C(0xff0000)
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_RECOMMEND_ROCE_PRIORITY_SFT \
+ 16
+ /* none is 255 */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_RECOMMEND_ROCE_PRIORITY_NONE \
+ (UINT32_C(0xff) << 16)
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_RECOMMEND_ROCE_PRIORITY_LAST \
+ HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_RECOMMEND_ROCE_PRIORITY_NONE
+ /* Priority recommended for L2 traffic */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_RECOMMEND_L2_PRIORITY_MASK \
+ UINT32_C(0xff000000)
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_RECOMMEND_L2_PRIORITY_SFT \
+ 24
+ /* none is 255 */
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_RECOMMEND_L2_PRIORITY_NONE \
+ (UINT32_C(0xff) << 24)
+ #define HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_RECOMMEND_L2_PRIORITY_LAST \
+ HWRM_ASYNC_EVENT_CMPL_DCB_CONFIG_CHANGE_EVENT_DATA1_RECOMMEND_L2_PRIORITY_NONE
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_port_conn_not_allowed (size:128b/16B) */
+struct hwrm_async_event_cmpl_port_conn_not_allowed {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_TYPE_SFT \
+ 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Port connection not allowed */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_ID_PORT_CONN_NOT_ALLOWED \
+ UINT32_C(0x4)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_ID_PORT_CONN_NOT_ALLOWED
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* PORT ID */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_PORT_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_PORT_ID_SFT \
+ 0
+ /*
+ * This value indicates the current port level enforcement policy
+ * for the optics module when there is an optical module mismatch
+ * and port is not connected.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_ENFORCEMENT_POLICY_MASK \
+ UINT32_C(0xff0000)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_ENFORCEMENT_POLICY_SFT \
+ 16
+ /* No enforcement */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_ENFORCEMENT_POLICY_NONE \
+ (UINT32_C(0x0) << 16)
+ /* Disable Transmit side Laser. */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_ENFORCEMENT_POLICY_DISABLETX \
+ (UINT32_C(0x1) << 16)
+ /* Raise a warning message. */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_ENFORCEMENT_POLICY_WARNINGMSG \
+ (UINT32_C(0x2) << 16)
+ /* Power down the module. */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_ENFORCEMENT_POLICY_PWRDOWN \
+ (UINT32_C(0x3) << 16)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_ENFORCEMENT_POLICY_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_ENFORCEMENT_POLICY_PWRDOWN
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_link_speed_cfg_not_allowed (size:128b/16B) */
+struct hwrm_async_event_cmpl_link_speed_cfg_not_allowed {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_TYPE_SFT \
+ 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Link speed configuration was not allowed */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED \
+ UINT32_C(0x5)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* PORT ID */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_EVENT_DATA1_PORT_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_NOT_ALLOWED_EVENT_DATA1_PORT_ID_SFT \
+ 0
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_link_speed_cfg_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_link_speed_cfg_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_TYPE_SFT \
+ 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Link speed configuration change */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_EVENT_ID_LINK_SPEED_CFG_CHANGE \
+ UINT32_C(0x6)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_EVENT_ID_LINK_SPEED_CFG_CHANGE
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* PORT ID */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_EVENT_DATA1_PORT_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_EVENT_DATA1_PORT_ID_SFT \
+ 0
+ /*
+ * If set to 1, it indicates that the supported link speeds
+ * configuration on the port has changed.
+ * If set to 0, then there is no change in supported link speeds
+ * configuration.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_EVENT_DATA1_SUPPORTED_LINK_SPEEDS_CHANGE \
+ UINT32_C(0x10000)
+ /*
+ * If set to 1, it indicates that the link speed configuration
+ * on the port has become illegal or invalid.
+ * If set to 0, then the link speed configuration on the port is
+ * legal or valid.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LINK_SPEED_CFG_CHANGE_EVENT_DATA1_ILLEGAL_LINK_SPEED_CFG \
+ UINT32_C(0x20000)
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_port_phy_cfg_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_port_phy_cfg_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_TYPE_SFT \
+ 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Port PHY configuration change */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_EVENT_ID_PORT_PHY_CFG_CHANGE \
+ UINT32_C(0x7)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_EVENT_ID_PORT_PHY_CFG_CHANGE
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* PORT ID */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_EVENT_DATA1_PORT_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_EVENT_DATA1_PORT_ID_SFT \
+ 0
+ /*
+ * If set to 1, it indicates that the FEC
+ * configuration on the port has changed.
+ * If set to 0, then there is no change in FEC configuration.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_EVENT_DATA1_FEC_CFG_CHANGE \
+ UINT32_C(0x10000)
+ /*
+ * If set to 1, it indicates that the EEE configuration
+ * on the port has changed.
+ * If set to 0, then there is no change in EEE configuration
+ * on the port.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_EVENT_DATA1_EEE_CFG_CHANGE \
+ UINT32_C(0x20000)
+ /*
+ * If set to 1, it indicates that the pause configuration
+ * on the PHY has changed.
+ * If set to 0, then there is no change in the pause
+ * configuration on the PHY.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PORT_PHY_CFG_CHANGE_EVENT_DATA1_PAUSE_CFG_CHANGE \
+ UINT32_C(0x40000)
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_func_drvr_unload (size:128b/16B) */
+struct hwrm_async_event_cmpl_func_drvr_unload {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Function driver unloaded */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_EVENT_ID_FUNC_DRVR_UNLOAD \
+ UINT32_C(0x10)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_EVENT_ID_FUNC_DRVR_UNLOAD
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_V UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* Function ID */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_EVENT_DATA1_FUNC_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_UNLOAD_EVENT_DATA1_FUNC_ID_SFT \
+ 0
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_func_drvr_load (size:128b/16B) */
+struct hwrm_async_event_cmpl_func_drvr_load {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Function driver loaded */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_EVENT_ID_FUNC_DRVR_LOAD \
+ UINT32_C(0x11)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_EVENT_ID_FUNC_DRVR_LOAD
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_V UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_OPAQUE_MASK UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* Function ID */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_EVENT_DATA1_FUNC_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_DRVR_LOAD_EVENT_DATA1_FUNC_ID_SFT 0
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_func_flr_proc_cmplt (size:128b/16B) */
+struct hwrm_async_event_cmpl_func_flr_proc_cmplt {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_TYPE_SFT \
+ 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Function FLR related processing has completed */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_EVENT_ID_FUNC_FLR_PROC_CMPLT \
+ UINT32_C(0x12)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_EVENT_ID_FUNC_FLR_PROC_CMPLT
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* Function ID */
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_EVENT_DATA1_FUNC_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_FUNC_FLR_PROC_CMPLT_EVENT_DATA1_FUNC_ID_SFT \
+ 0
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_pf_drvr_unload (size:128b/16B) */
+struct hwrm_async_event_cmpl_pf_drvr_unload {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* PF driver unloaded */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_EVENT_ID_PF_DRVR_UNLOAD \
+ UINT32_C(0x20)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_EVENT_ID_PF_DRVR_UNLOAD
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_V UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_OPAQUE_MASK UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* PF ID */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_EVENT_DATA1_FUNC_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_EVENT_DATA1_FUNC_ID_SFT 0
+ /* Indicates the physical port this pf belongs to */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_EVENT_DATA1_PORT_MASK \
+ UINT32_C(0x70000)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_UNLOAD_EVENT_DATA1_PORT_SFT 16
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_pf_drvr_load (size:128b/16B) */
+struct hwrm_async_event_cmpl_pf_drvr_load {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* PF driver loaded */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_EVENT_ID_PF_DRVR_LOAD \
+ UINT32_C(0x21)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_EVENT_ID_PF_DRVR_LOAD
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_V UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_OPAQUE_MASK UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* PF ID */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_EVENT_DATA1_FUNC_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_EVENT_DATA1_FUNC_ID_SFT 0
+ /* Indicates the physical port this pf belongs to */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_EVENT_DATA1_PORT_MASK \
+ UINT32_C(0x70000)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_DRVR_LOAD_EVENT_DATA1_PORT_SFT 16
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_vf_flr (size:128b/16B) */
+struct hwrm_async_event_cmpl_vf_flr {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_VF_FLR_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* VF Function Level Reset (FLR) */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_ID_VF_FLR UINT32_C(0x30)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_ID_VF_FLR
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_V UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_OPAQUE_MASK UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* VF ID */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_VF_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_VF_ID_SFT 0
+ /* Indicates the physical function this event occured on. */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_PF_ID_MASK \
+ UINT32_C(0xff0000)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_PF_ID_SFT 16
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_vf_mac_addr_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_vf_mac_addr_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* VF MAC Address Change */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_EVENT_ID_VF_MAC_ADDR_CHANGE \
+ UINT32_C(0x31)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_EVENT_ID_VF_MAC_ADDR_CHANGE
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* VF ID */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_EVENT_DATA1_VF_ID_MASK \
+ UINT32_C(0xffff)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_MAC_ADDR_CHANGE_EVENT_DATA1_VF_ID_SFT \
+ 0
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_pf_vf_comm_status_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_pf_vf_comm_status_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_TYPE_SFT \
+ 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* PF-VF communication channel status change. */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_EVENT_ID_PF_VF_COMM_STATUS_CHANGE \
+ UINT32_C(0x32)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_EVENT_ID_PF_VF_COMM_STATUS_CHANGE
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /*
+ * If this bit is set to 1, then it indicates that the PF-VF
+ * communication was lost and it is established.
+ * If this bit set to 0, then it indicates that the PF-VF
+ * communication was established and it is lost.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_PF_VF_COMM_STATUS_CHANGE_EVENT_DATA1_COMM_ESTABLISHED \
+ UINT32_C(0x1)
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_vf_cfg_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_vf_cfg_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* VF Configuration Change */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_EVENT_ID_VF_CFG_CHANGE \
+ UINT32_C(0x33)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_EVENT_ID_VF_CFG_CHANGE
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_V UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_OPAQUE_MASK UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /*
+ * Each flag provided in this field indicates a specific VF
+ * configuration change. At least one of these flags shall be set to 1
+ * when an asynchronous event completion of this type is provided
+ * by the HWRM.
+ */
+ uint32_t event_data1;
+ /*
+ * If this bit is set to 1, then the value of MTU
+ * was changed on this VF.
+ * If set to 0, then this bit should be ignored.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_EVENT_DATA1_MTU_CHANGE \
+ UINT32_C(0x1)
+ /*
+ * If this bit is set to 1, then the value of MRU
+ * was changed on this VF.
+ * If set to 0, then this bit should be ignored.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_EVENT_DATA1_MRU_CHANGE \
+ UINT32_C(0x2)
+ /*
+ * If this bit is set to 1, then the value of default MAC
+ * address was changed on this VF.
+ * If set to 0, then this bit should be ignored.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_EVENT_DATA1_DFLT_MAC_ADDR_CHANGE \
+ UINT32_C(0x4)
+ /*
+ * If this bit is set to 1, then the value of default VLAN
+ * was changed on this VF.
+ * If set to 0, then this bit should be ignored.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_VF_CFG_CHANGE_EVENT_DATA1_DFLT_VLAN_CHANGE \
+ UINT32_C(0x8)
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_llfc_pfc_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_llfc_pfc_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* unused1 is 10 b */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_UNUSED1_MASK \
+ UINT32_C(0xffc0)
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_UNUSED1_SFT 6
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* LLFC/PFC Configuration Change */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_ID_LLFC_PFC_CHANGE \
+ UINT32_C(0x34)
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_ID_LLFC_PFC_CHANGE
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_V UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* Indicates llfc pfc status change */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_DATA1_LLFC_PFC_MASK \
+ UINT32_C(0x3)
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_DATA1_LLFC_PFC_SFT \
+ 0
+ /*
+ * If this field set to 1, then it indicates that llfc is
+ * enabled.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_DATA1_LLFC_PFC_LLFC \
+ UINT32_C(0x1)
+ /*
+ * If this field is set to 2, then it indicates that pfc
+ * is enabled.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_DATA1_LLFC_PFC_PFC \
+ UINT32_C(0x2)
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_DATA1_LLFC_PFC_LAST \
+ HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_DATA1_LLFC_PFC_PFC
+ /* Indicates the physical port this llfc pfc change occur */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_DATA1_PORT_MASK \
+ UINT32_C(0x1c)
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_DATA1_PORT_SFT \
+ 2
+ /* PORT ID */
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_DATA1_PORT_ID_MASK \
+ UINT32_C(0x1fffe0)
+ #define HWRM_ASYNC_EVENT_CMPL_LLFC_PFC_CHANGE_EVENT_DATA1_PORT_ID_SFT \
+ 5
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_default_vnic_change (size:128b/16B) */
+struct hwrm_async_event_cmpl_default_vnic_change {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_TYPE_SFT \
+ 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_TYPE_HWRM_ASYNC_EVENT
+ /* unused1 is 10 b */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_UNUSED1_MASK \
+ UINT32_C(0xffc0)
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_UNUSED1_SFT \
+ 6
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* Notification of a default vnic allocaiton or free */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_ID_ALLOC_FREE_NOTIFICATION \
+ UINT32_C(0x35)
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_ID_ALLOC_FREE_NOTIFICATION
+ /* Event specific data */
+ uint32_t event_data2;
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_V \
+ UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_OPAQUE_MASK \
+ UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* Indicates default vnic configuration change */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_MASK \
+ UINT32_C(0x3)
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_SFT \
+ 0
+ /*
+ * If this field is set to 1, then it indicates that
+ * a default VNIC has been allocate.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_DEF_VNIC_ALLOC \
+ UINT32_C(0x1)
+ /*
+ * If this field is set to 2, then it indicates that
+ * a default VNIC has been freed.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_DEF_VNIC_FREE \
+ UINT32_C(0x2)
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_DEF_VNIC_FREE
+ /* Indicates the physical function this event occured on. */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_PF_ID_MASK \
+ UINT32_C(0x3fc)
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_PF_ID_SFT \
+ 2
+ /* Indicates the virtual function this event occured on */
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_VF_ID_MASK \
+ UINT32_C(0x3fffc00)
+ #define HWRM_ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_VF_ID_SFT \
+ 10
+} __attribute__((packed));
+
+/* hwrm_async_event_cmpl_hwrm_error (size:128b/16B) */
+struct hwrm_async_event_cmpl_hwrm_error {
+ uint16_t type;
+ /*
+ * This field indicates the exact type of the completion.
+ * By convention, the LSB identifies the length of the
+ * record in 16B units. Even values indicate 16B
+ * records. Odd values indicate 32B
+ * records.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_TYPE_MASK \
+ UINT32_C(0x3f)
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_TYPE_SFT 0
+ /* HWRM Asynchronous Event Information */
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_TYPE_HWRM_ASYNC_EVENT \
+ UINT32_C(0x2e)
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_TYPE_LAST \
+ HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_TYPE_HWRM_ASYNC_EVENT
+ /* Identifiers of events. */
+ uint16_t event_id;
+ /* HWRM Error */
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_ID_HWRM_ERROR \
+ UINT32_C(0xff)
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_ID_LAST \
+ HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_ID_HWRM_ERROR
+ /* Event specific data */
+ uint32_t event_data2;
+ /* Severity of HWRM Error */
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_DATA2_SEVERITY_MASK \
+ UINT32_C(0xff)
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_DATA2_SEVERITY_SFT 0
+ /* Warning */
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_DATA2_SEVERITY_WARNING \
+ UINT32_C(0x0)
+ /* Non-fatal Error */
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_DATA2_SEVERITY_NONFATAL \
+ UINT32_C(0x1)
+ /* Fatal Error */
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_DATA2_SEVERITY_FATAL \
+ UINT32_C(0x2)
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_DATA2_SEVERITY_LAST \
+ HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_DATA2_SEVERITY_FATAL
+ uint8_t opaque_v;
+ /*
+ * This value is written by the NIC such that it will be different
+ * for each pass through the completion queue. The even passes
+ * will write 1. The odd passes will write 0.
+ */
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_V UINT32_C(0x1)
+ /* opaque is 7 b */
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_OPAQUE_MASK UINT32_C(0xfe)
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_OPAQUE_SFT 1
+ /* 8-lsb timestamp from POR (100-msec resolution) */
+ uint8_t timestamp_lo;
+ /* 16-lsb timestamp from POR (100-msec resolution) */
+ uint16_t timestamp_hi;
+ /* Event specific data */
+ uint32_t event_data1;
+ /* Time stamp for error event */
+ #define HWRM_ASYNC_EVENT_CMPL_HWRM_ERROR_EVENT_DATA1_TIMESTAMP \
+ UINT32_C(0x1)
+} __attribute__((packed));
+
+/*******************
+ * hwrm_func_reset *
+ *******************/
+
+
+/* hwrm_func_reset_input (size:192b/24B) */
+struct hwrm_func_reset_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the vf_id_valid field to be
+ * configured.
+ */
+ #define HWRM_FUNC_RESET_INPUT_ENABLES_VF_ID_VALID UINT32_C(0x1)
+ /*
+ * The ID of the VF that this PF is trying to reset.
+ * Only the parent PF shall be allowed to reset a child VF.
+ *
+ * A parent PF driver shall use this field only when a specific child VF
+ * is requested to be reset.
+ */
+ uint16_t vf_id;
+ /* This value indicates the level of a function reset. */
+ uint8_t func_reset_level;
+ /*
+ * Reset the caller function and its children VFs (if any). If no
+ * children functions exist, then reset the caller function only.
+ */
+ #define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETALL \
+ UINT32_C(0x0)
+ /* Reset the caller function only */
+ #define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETME \
+ UINT32_C(0x1)
+ /*
+ * Reset all children VFs of the caller function driver if the
+ * caller is a PF driver.
+ * It is an error to specify this level by a VF driver.
+ * It is an error to specify this level by a PF driver with
+ * no children VFs.
+ */
+ #define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETCHILDREN \
+ UINT32_C(0x2)
+ /*
+ * Reset a specific VF of the caller function driver if the caller
+ * is the parent PF driver.
+ * It is an error to specify this level by a VF driver.
+ * It is an error to specify this level by a PF driver that is not
+ * the parent of the VF that is being requested to reset.
+ */
+ #define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETVF \
+ UINT32_C(0x3)
+ #define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_LAST \
+ HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETVF
+ uint8_t unused_0;
+} __attribute__((packed));
+
+/* hwrm_func_reset_output (size:128b/16B) */
+struct hwrm_func_reset_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_getfid *
+ ********************/
+
+
+/* hwrm_func_getfid_input (size:192b/24B) */
+struct hwrm_func_getfid_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the pci_id field to be
+ * configured.
+ */
+ #define HWRM_FUNC_GETFID_INPUT_ENABLES_PCI_ID UINT32_C(0x1)
+ /*
+ * This value is the PCI ID of the queried function.
+ * If ARI is enabled, then it is
+ * Bus Number (8b):Function Number(8b). Otherwise, it is
+ * Bus Number (8b):Device Number (5b):Function Number(3b).
+ */
+ uint16_t pci_id;
+ uint8_t unused_0[2];
+} __attribute__((packed));
+
+/* hwrm_func_getfid_output (size:128b/16B) */
+struct hwrm_func_getfid_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ 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;
+ uint8_t unused_0[5];
+ /*
+ * 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_func_vf_alloc *
+ **********************/
+
+
+/* hwrm_func_vf_alloc_input (size:192b/24B) */
+struct hwrm_func_vf_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the first_vf_id field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_ALLOC_INPUT_ENABLES_FIRST_VF_ID UINT32_C(0x1)
+ /*
+ * This value is used to identify a Virtual Function (VF).
+ * The scope of VF ID is local within a PF.
+ */
+ uint16_t first_vf_id;
+ /* The number of virtual functions requested. */
+ uint16_t num_vfs;
+} __attribute__((packed));
+
+/* hwrm_func_vf_alloc_output (size:128b/16B) */
+struct hwrm_func_vf_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* The ID of the first VF allocated. */
+ uint16_t first_vf_id;
+ uint8_t unused_0[5];
+ /*
+ * 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_func_vf_free *
+ *********************/
+
+
+/* hwrm_func_vf_free_input (size:192b/24B) */
+struct hwrm_func_vf_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the first_vf_id field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_FREE_INPUT_ENABLES_FIRST_VF_ID UINT32_C(0x1)
+ /*
+ * This value is used to identify a Virtual Function (VF).
+ * The scope of VF ID is local within a PF.
+ */
+ uint16_t first_vf_id;
+ /*
+ * The number of virtual functions requested.
+ * 0xFFFF - Cleanup all children of this PF.
+ */
+ uint16_t num_vfs;
+} __attribute__((packed));
+
+/* hwrm_func_vf_free_output (size:128b/16B) */
+struct hwrm_func_vf_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_vf_cfg *
+ ********************/
+
+
+/* hwrm_func_vf_cfg_input (size:448b/56B) */
+struct hwrm_func_vf_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the mtu field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_MTU \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the guest_vlan field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_GUEST_VLAN \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the async_event_cr field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_ASYNC_EVENT_CR \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the dflt_mac_addr field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the num_rsscos_ctxs field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the num_cmpl_rings field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_CMPL_RINGS \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the num_tx_rings field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_TX_RINGS \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the num_rx_rings field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_RX_RINGS \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the num_l2_ctxs field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_L2_CTXS \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the num_vnics field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_VNICS \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the num_stat_ctxs field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_STAT_CTXS \
+ UINT32_C(0x400)
+ /*
+ * This bit must be '1' for the num_hw_ring_grps field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS \
+ UINT32_C(0x800)
+ /*
+ * The maximum transmission unit requested on the function.
+ * The HWRM should make sure that the mtu of
+ * the function does not exceed the mtu of the physical
+ * port that this function is associated with.
+ *
+ * In addition to requesting mtu per function, it is
+ * possible to configure mtu per transmit ring.
+ * By default, the mtu of each transmit ring associated
+ * with a function is equal to the mtu of the function.
+ * The HWRM should make sure that the mtu of each transmit
+ * ring that is assigned to a function has a valid mtu.
+ */
+ uint16_t mtu;
+ /*
+ * The guest VLAN for the function being configured.
+ * This field's format is same as 802.1Q Tag's
+ * Tag Control Information (TCI) format that includes both
+ * Priority Code Point (PCP) and VLAN Identifier (VID).
+ */
+ uint16_t guest_vlan;
+ /*
+ * ID of the target completion ring for receiving asynchronous
+ * event completions. If this field is not valid, then the
+ * HWRM shall use the default completion ring of the function
+ * that is being configured as the target completion ring for
+ * providing any asynchronous event completions for that
+ * function.
+ * If this field is valid, then the HWRM shall use the
+ * completion ring identified by this ID as the target
+ * completion ring for providing any asynchronous event
+ * completions for the function that is being configured.
+ */
+ uint16_t async_event_cr;
+ /*
+ * This value is the current MAC address requested by the VF
+ * driver to be configured on this VF. A value of
+ * 00-00-00-00-00-00 indicates no MAC address configuration
+ * is requested by the VF driver.
+ * The parent PF driver may reject or overwrite this
+ * MAC address.
+ */
+ uint8_t dflt_mac_addr[6];
+ uint32_t flags;
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of TX rings) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_FLAGS_TX_ASSETS_TEST \
+ UINT32_C(0x1)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of RX rings) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_FLAGS_RX_ASSETS_TEST \
+ UINT32_C(0x2)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of CMPL rings) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_FLAGS_CMPL_ASSETS_TEST \
+ UINT32_C(0x4)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of RSS ctx) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_FLAGS_RSSCOS_CTX_ASSETS_TEST \
+ UINT32_C(0x8)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of ring groups) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_FLAGS_RING_GRP_ASSETS_TEST \
+ UINT32_C(0x10)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of stat ctx) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_FLAGS_STAT_CTX_ASSETS_TEST \
+ UINT32_C(0x20)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of VNICs) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_FLAGS_VNIC_ASSETS_TEST \
+ UINT32_C(0x40)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of L2 ctx) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_VF_CFG_INPUT_FLAGS_L2_CTX_ASSETS_TEST \
+ UINT32_C(0x80)
+ /* The number of RSS/COS contexts requested for the VF. */
+ uint16_t num_rsscos_ctxs;
+ /* The number of completion rings requested for the VF. */
+ uint16_t num_cmpl_rings;
+ /* The number of transmit rings requested for the VF. */
+ uint16_t num_tx_rings;
+ /* The number of receive rings requested for the VF. */
+ uint16_t num_rx_rings;
+ /* The number of L2 contexts requested for the VF. */
+ uint16_t num_l2_ctxs;
+ /* The number of vnics requested for the VF. */
+ uint16_t num_vnics;
+ /* The number of statistic contexts requested for the VF. */
+ uint16_t num_stat_ctxs;
+ /* The number of HW ring groups requested for the VF. */
+ uint16_t num_hw_ring_grps;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_func_vf_cfg_output (size:128b/16B) */
+struct hwrm_func_vf_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_qcaps *
+ *******************/
+
+
+/* hwrm_func_qcaps_input (size:192b/24B) */
+struct hwrm_func_qcaps_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ 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;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_func_qcaps_output (size:640b/80B) */
+struct hwrm_func_qcaps_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ 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;
+ uint32_t flags;
+ /* 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)
+ /*
+ * If 1, then RDMA over Converged Ethernet (RoCE) v1
+ * is supported on this function.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V1_SUPPORTED \
+ UINT32_C(0x8)
+ /*
+ * If 1, then RDMA over Converged Ethernet (RoCE) v2
+ * is supported on this function.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V2_SUPPORTED \
+ UINT32_C(0x10)
+ /*
+ * If 1, then control and configuration of WoL magic packet
+ * are supported on this function.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED \
+ UINT32_C(0x20)
+ /*
+ * If 1, then control and configuration of bitmap pattern
+ * packet are supported on this function.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_BMP_SUPPORTED \
+ UINT32_C(0x40)
+ /*
+ * If set to 1, then the control and configuration of rate limit
+ * of an allocated TX ring on the queried function is supported.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_RING_RL_SUPPORTED \
+ UINT32_C(0x80)
+ /*
+ * If 1, then control and configuration of minimum and
+ * maximum bandwidths are supported on the queried function.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_BW_CFG_SUPPORTED \
+ UINT32_C(0x100)
+ /*
+ * If the query is for a VF, then this flag shall be ignored.
+ * If this query is for a PF and this flag is set to 1,
+ * then the PF has the capability to set the rate limits
+ * on the TX rings of its children VFs.
+ * If this query is for a PF and this flag is set to 0, then
+ * the PF does not have the capability to set the rate limits
+ * on the TX rings of its children VFs.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_TX_RING_RL_SUPPORTED \
+ UINT32_C(0x200)
+ /*
+ * If the query is for a VF, then this flag shall be ignored.
+ * If this query is for a PF and this flag is set to 1,
+ * then the PF has the capability to set the minimum and/or
+ * maximum bandwidths for its children VFs.
+ * If this query is for a PF and this flag is set to 0, then
+ * the PF does not have the capability to set the minimum or
+ * maximum bandwidths for its children VFs.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_BW_CFG_SUPPORTED \
+ UINT32_C(0x400)
+ /*
+ * Standard TX Ring mode is used for the allocation of TX ring
+ * and underlying scheduling resources that allow bandwidth
+ * reservation and limit settings on the queried function.
+ * If set to 1, then standard TX ring mode is supported
+ * on the queried function.
+ * If set to 0, then standard TX ring mode is not available
+ * on the queried function.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_STD_TX_RING_MODE_SUPPORTED \
+ UINT32_C(0x800)
+ /*
+ * If the query is for a VF, then this flag shall be ignored,
+ * If this query is for a PF and this flag is set to 1,
+ * then the PF has the capability to detect GENEVE tunnel
+ * flags.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_GENEVE_TUN_FLAGS_SUPPORTED \
+ UINT32_C(0x1000)
+ /*
+ * If the query is for a VF, then this flag shall be ignored,
+ * If this query is for a PF and this flag is set to 1,
+ * then the PF has the capability to detect NVGRE tunnel
+ * flags.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_NVGRE_TUN_FLAGS_SUPPORTED \
+ UINT32_C(0x2000)
+ /*
+ * If the query is for a VF, then this flag shall be ignored,
+ * If this query is for a PF and this flag is set to 1,
+ * then the PF has the capability to detect GRE tunnel
+ * flags.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_GRE_TUN_FLAGS_SUPPORTED \
+ UINT32_C(0x4000)
+ /*
+ * If the query is for a VF, then this flag shall be ignored,
+ * If this query is for a PF and this flag is set to 1,
+ * then the PF has the capability to detect MPLS tunnel
+ * flags.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_MPLS_TUN_FLAGS_SUPPORTED \
+ UINT32_C(0x8000)
+ /*
+ * If the query is for a VF, then this flag shall be ignored,
+ * If this query is for a PF and this flag is set to 1,
+ * then the PF has the capability to support pcie stats.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PCIE_STATS_SUPPORTED \
+ UINT32_C(0x10000)
+ /*
+ * If the query is for a VF, then this flag shall be ignored,
+ * If this query is for a PF and this flag is set to 1,
+ * then the PF has the capability to adopt the VF's belonging
+ * to another PF.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ADOPTED_PF_SUPPORTED \
+ UINT32_C(0x20000)
+ /*
+ * If the query is for a VF, then this flag shall be ignored,
+ * If this query is for a PF and this flag is set to 1,
+ * then the PF has the capability to administer another PF.
+ */
+ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ADMIN_PF_SUPPORTED \
+ UINT32_C(0x40000)
+ /*
+ * 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 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;
+ /*
+ * The maximum number of strict priority transmit rings
+ * that can be allocated to the function.
+ * This number indicates the maximum number of TX rings
+ * that can be assigned strict priorities out of the
+ * maximum number of TX rings that can be allocated
+ * (max_tx_rings) to the function.
+ */
+ uint16_t max_sp_tx_rings;
+ uint8_t unused_0;
+ /*
+ * 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_func_qcfg *
+ ******************/
+
+
+/* hwrm_func_qcfg_input (size:192b/24B) */
+struct hwrm_func_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ 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;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_func_qcfg_output (size:640b/80B) */
+struct hwrm_func_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ 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.
+ * 0xFF... (All Fs) if this function is not associated with
+ * any port.
+ */
+ uint16_t port_id;
+ /*
+ * This value is the current VLAN setting for this
+ * function. The value of 0 for this field indicates
+ * no priority tagging or VLAN is used.
+ * This field's format is same as 802.1Q Tag's
+ * Tag Control Information (TCI) format that includes both
+ * Priority Code Point (PCP) and VLAN Identifier (VID).
+ */
+ uint16_t vlan;
+ uint16_t flags;
+ /*
+ * If 1, then magic packet based Out-Of-Box WoL is enabled on
+ * the port associated with this function.
+ */
+ #define HWRM_FUNC_QCFG_OUTPUT_FLAGS_OOB_WOL_MAGICPKT_ENABLED \
+ UINT32_C(0x1)
+ /*
+ * If 1, then bitmap pattern based Out-Of-Box WoL packet is enabled
+ * on the port associated with this function.
+ */
+ #define HWRM_FUNC_QCFG_OUTPUT_FLAGS_OOB_WOL_BMP_ENABLED \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, then FW based DCBX agent is enabled and running on
+ * the port associated with this function.
+ * If set to 0, then DCBX agent is not running in the firmware.
+ */
+ #define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED \
+ UINT32_C(0x4)
+ /*
+ * Standard TX Ring mode is used for the allocation of TX ring
+ * and underlying scheduling resources that allow bandwidth
+ * reservation and limit settings on the queried function.
+ * If set to 1, then standard TX ring mode is enabled
+ * on the queried function.
+ * If set to 0, then the standard TX ring mode is disabled
+ * on the queried function. In this extended TX ring resource
+ * mode, the minimum and maximum bandwidth settings are not
+ * supported to allow the allocation of TX rings to span multiple
+ * scheduler nodes.
+ */
+ #define HWRM_FUNC_QCFG_OUTPUT_FLAGS_STD_TX_RING_MODE_ENABLED \
+ UINT32_C(0x8)
+ /*
+ * If set to 1 then FW based LLDP agent is enabled and running on
+ * the port associated with this function.
+ * If set to 0 then the LLDP agent is not running in the firmware.
+ */
+ #define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_LLDP_AGENT_ENABLED \
+ UINT32_C(0x10)
+ /*
+ * If set to 1, then multi-host mode is active for this function.
+ * If set to 0, then multi-host mode is inactive for this function
+ * or not applicable for this device.
+ */
+ #define HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_HOST \
+ UINT32_C(0x20)
+ /*
+ * 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 mac_address[6];
+ /*
+ * This value is current PCI ID of this
+ * function. If ARI is enabled, then it is
+ * Bus Number (8b):Function Number(8b). Otherwise, it is
+ * Bus Number (8b):Device Number (4b):Function Number(4b).
+ * If multi-host mode is active, the 4 lsb will indicate
+ * the PF index for this function.
+ */
+ uint16_t pci_id;
+ /*
+ * The number of RSS/COS contexts currently
+ * allocated to the function.
+ */
+ uint16_t alloc_rsscos_ctx;
+ /*
+ * The number of completion rings currently allocated to
+ * the function. This does not include the rings allocated
+ * to any children functions if any.
+ */
+ uint16_t alloc_cmpl_rings;
+ /*
+ * The number of transmit rings currently allocated to
+ * the function. This does not include the rings allocated
+ * to any children functions if any.
+ */
+ uint16_t alloc_tx_rings;
+ /*
+ * The number of receive rings currently allocated to
+ * the function. This does not include the rings allocated
+ * to any children functions if any.
+ */
+ uint16_t alloc_rx_rings;
+ /* The allocated number of L2 contexts to the function. */
+ uint16_t alloc_l2_ctx;
+ /* The allocated number of vnics to the function. */
+ uint16_t alloc_vnics;
+ /*
+ * The maximum transmission unit of the function.
+ * For rings allocated on this function, this default
+ * value is used if ring MTU is not specified.
+ */
+ uint16_t mtu;
+ /*
+ * The maximum receive unit of the function.
+ * For vnics allocated on this function, this default
+ * value is used if vnic MRU is not specified.
+ */
+ uint16_t mru;
+ /* The statistics context assigned to a function. */
+ uint16_t stat_ctx_id;
+ /*
+ * The HWRM shall return Unknown value for this field
+ * when this command is used to query VF's configuration.
+ */
+ uint8_t port_partition_type;
+ /* Single physical function */
+ #define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_SPF UINT32_C(0x0)
+ /* Multiple physical functions */
+ #define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_MPFS UINT32_C(0x1)
+ /* Network Partitioning 1.0 */
+ #define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0 UINT32_C(0x2)
+ /* Network Partitioning 1.5 */
+ #define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5 UINT32_C(0x3)
+ /* Network Partitioning 2.0 */
+ #define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0 UINT32_C(0x4)
+ /* Unknown */
+ #define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN \
+ UINT32_C(0xff)
+ #define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_LAST \
+ HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN
+ /*
+ * This field will indicate number of physical functions on this port_partition.
+ * HWRM shall return unavail (i.e. value of 0) for this field
+ * when this command is used to query VF's configuration or
+ * from older firmware that doesn't support this field.
+ */
+ uint8_t port_pf_cnt;
+ /* number of PFs is not available */
+ #define HWRM_FUNC_QCFG_OUTPUT_PORT_PF_CNT_UNAVAIL UINT32_C(0x0)
+ #define HWRM_FUNC_QCFG_OUTPUT_PORT_PF_CNT_LAST \
+ HWRM_FUNC_QCFG_OUTPUT_PORT_PF_CNT_UNAVAIL
+ /*
+ * The default VNIC ID assigned to a function that is
+ * being queried.
+ */
+ uint16_t dflt_vnic_id;
+ uint16_t max_mtu_configured;
+ /*
+ * Minimum BW allocated for this function.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for the scheduler inside the device.
+ * A value of 0 indicates the minimum bandwidth is not
+ * configured.
+ */
+ uint32_t min_bw;
+ /* The bandwidth value. */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_SFT 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_LAST \
+ HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_SFT 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated for this function.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for the scheduler inside the device.
+ * A value of 0 indicates that the maximum bandwidth is not
+ * configured.
+ */
+ uint32_t max_bw;
+ /* The bandwidth value. */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_SFT 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_LAST \
+ HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_SFT 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * This value indicates the Edge virtual bridge mode for the
+ * domain that this function belongs to.
+ */
+ uint8_t evb_mode;
+ /* No Edge Virtual Bridging (EVB) */
+ #define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_NO_EVB UINT32_C(0x0)
+ /* Virtual Ethernet Bridge (VEB) */
+ #define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEB UINT32_C(0x1)
+ /* Virtual Ethernet Port Aggregator (VEPA) */
+ #define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEPA UINT32_C(0x2)
+ #define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_LAST \
+ HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEPA
+ uint8_t options;
+ /*
+ * This value indicates the PCIE device cache line size.
+ * The cache line size allows the DMA writes to terminate and
+ * start at the cache boundary.
+ */
+ #define HWRM_FUNC_QCFG_OUTPUT_OPTIONS_CACHE_LINESIZE_MASK \
+ UINT32_C(0x3)
+ #define HWRM_FUNC_QCFG_OUTPUT_OPTIONS_CACHE_LINESIZE_SFT 0
+ /* Cache Line Size 64 bytes */
+ #define HWRM_FUNC_QCFG_OUTPUT_OPTIONS_CACHE_LINESIZE_SIZE_64 \
+ UINT32_C(0x0)
+ /* Cache Line Size 128 bytes */
+ #define HWRM_FUNC_QCFG_OUTPUT_OPTIONS_CACHE_LINESIZE_SIZE_128 \
+ UINT32_C(0x1)
+ #define HWRM_FUNC_QCFG_OUTPUT_OPTIONS_CACHE_LINESIZE_LAST \
+ HWRM_FUNC_QCFG_OUTPUT_OPTIONS_CACHE_LINESIZE_SIZE_128
+ /* Reserved for future. */
+ #define HWRM_FUNC_QCFG_OUTPUT_OPTIONS_RSVD_MASK \
+ UINT32_C(0xfc)
+ #define HWRM_FUNC_QCFG_OUTPUT_OPTIONS_RSVD_SFT 2
+ /*
+ * The number of VFs that are 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 alloc_vfs;
+ /*
+ * The number of allocated multicast filters for this
+ * function on the RX side.
+ */
+ uint32_t alloc_mcast_filters;
+ /*
+ * The number of allocated HW ring groups for this
+ * function.
+ */
+ uint32_t alloc_hw_ring_grps;
+ /*
+ * The number of strict priority transmit rings out of
+ * currently allocated TX rings to the function
+ * (alloc_tx_rings).
+ */
+ uint16_t alloc_sp_tx_rings;
+ /*
+ * The number of statistics contexts
+ * currently reserved for the function.
+ */
+ uint16_t alloc_stat_ctx;
+ /*
+ * This field specifies how many NQs are reserved for the PF.
+ * Remaining NQs that belong to the PF are available for VFs.
+ * Once a PF has created VFs, it cannot change how many NQs are
+ * reserved for itself (since the NQs must be contiguous in HW).
+ */
+ uint16_t alloc_msix;
+ uint8_t unused_2[5];
+ /*
+ * 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_func_vlan_qcfg *
+ ***********************/
+
+
+/* hwrm_func_vlan_qcfg_input (size:192b/24B) */
+struct hwrm_func_vlan_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * Function ID of the function that is being
+ * configured.
+ * If set to 0xFF... (All Fs), then the configuration is
+ * for the requesting function.
+ */
+ uint16_t fid;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_func_vlan_qcfg_output (size:320b/40B) */
+struct hwrm_func_vlan_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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;
+ /* S-TAG VLAN identifier configured for the function. */
+ uint16_t stag_vid;
+ /* S-TAG PCP value configured for the function. */
+ uint8_t stag_pcp;
+ uint8_t unused_1;
+ /*
+ * S-TAG TPID value configured for the function. This field is specified in
+ * network byte order.
+ */
+ uint16_t stag_tpid;
+ /* C-TAG VLAN identifier configured for the function. */
+ uint16_t ctag_vid;
+ /* C-TAG PCP value configured for the function. */
+ uint8_t ctag_pcp;
+ uint8_t unused_2;
+ /*
+ * C-TAG TPID value configured for the function. This field is specified in
+ * network byte order.
+ */
+ uint16_t ctag_tpid;
+ /* Future use. */
+ uint32_t rsvd2;
+ /* Future use. */
+ uint32_t rsvd3;
+ uint32_t unused_3;
+} __attribute__((packed));
+
+/**********************
+ * hwrm_func_vlan_cfg *
+ **********************/
+
+
+/* hwrm_func_vlan_cfg_input (size:384b/48B) */
+struct hwrm_func_vlan_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * Function ID of the function that is being
+ * configured.
+ * If set to 0xFF... (All Fs), then the configuration is
+ * for the requesting function.
+ */
+ uint16_t fid;
+ uint8_t unused_0[2];
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the stag_vid field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_VID UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the ctag_vid field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_VID UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the stag_pcp field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_PCP UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the ctag_pcp field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_PCP UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the stag_tpid field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_TPID UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the ctag_tpid field to be
+ * configured.
+ */
+ #define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_TPID UINT32_C(0x20)
+ /* S-TAG VLAN identifier configured for the function. */
+ uint16_t stag_vid;
+ /* S-TAG PCP value configured for the function. */
+ uint8_t stag_pcp;
+ uint8_t unused_1;
+ /*
+ * S-TAG TPID value configured for the function. This field is specified in
+ * network byte order.
+ */
+ uint16_t stag_tpid;
+ /* C-TAG VLAN identifier configured for the function. */
+ uint16_t ctag_vid;
+ /* C-TAG PCP value configured for the function. */
+ uint8_t ctag_pcp;
+ uint8_t unused_2;
+ /*
+ * C-TAG TPID value configured for the function. This field is specified in
+ * network byte order.
+ */
+ uint16_t ctag_tpid;
+ /* Future use. */
+ uint32_t rsvd1;
+ /* Future use. */
+ uint32_t rsvd2;
+ uint8_t unused_3[4];
+} __attribute__((packed));
+
+/* hwrm_func_vlan_cfg_output (size:128b/16B) */
+struct hwrm_func_vlan_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_cfg *
+ *****************/
+
+
+/* hwrm_func_cfg_input (size:704b/88B) */
+struct hwrm_func_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * Function ID of the function that is being
+ * configured.
+ * If set to 0xFF... (All Fs), then the the configuration is
+ * for the requesting function.
+ */
+ uint16_t fid;
+ /*
+ * This field specifies how many NQs will be reserved for the PF.
+ * Remaining NQs that belong to the PF become available for VFs.
+ * Once a PF has created VFs, it cannot change how many NQs are
+ * reserved for itself (since the NQs must be contiguous in HW).
+ */
+ uint16_t num_msix;
+ uint32_t flags;
+ /*
+ * When this bit is '1', the function is disabled with
+ * source MAC address check.
+ * This is an anti-spoofing check. If this flag is set,
+ * then the function shall be configured to disallow
+ * transmission of frames with the source MAC address that
+ * is configured for this function.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', the function is enabled with
+ * source MAC address check.
+ * This is an anti-spoofing check. If this flag is set,
+ * then the function shall be configured to allow
+ * transmission of frames with the source MAC address that
+ * is configured for this function.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_RSVD_MASK \
+ UINT32_C(0x1fc)
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_RSVD_SFT 2
+ /*
+ * Standard TX Ring mode is used for the allocation of TX ring
+ * and underlying scheduling resources that allow bandwidth
+ * reservation and limit settings on the queried function.
+ * If set to 1, then standard TX ring mode is requested to be
+ * enabled on the function being configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE \
+ UINT32_C(0x200)
+ /*
+ * Standard TX Ring mode is used for the allocation of TX ring
+ * and underlying scheduling resources that allow bandwidth
+ * reservation and limit settings on the queried function.
+ * If set to 1, then the standard TX ring mode is requested to
+ * be disabled on the function being configured. In this extended
+ * TX ring resource mode, the minimum and maximum bandwidth settings
+ * are not supported to allow the allocation of TX rings to
+ * span multiple scheduler nodes.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE \
+ UINT32_C(0x400)
+ /*
+ * If this bit is set, virtual mac address configured
+ * in this command will be persistent over warm boot.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_VIRT_MAC_PERSIST \
+ UINT32_C(0x800)
+ /*
+ * This bit only applies to the VF. If this bit is set, the statistic
+ * context counters will not be cleared when the statistic context is freed
+ * or a function reset is called on VF. This bit will be cleared when the PF
+ * is unloaded or a function reset is called on the PF.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC \
+ UINT32_C(0x1000)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of TX rings) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_TX_ASSETS_TEST \
+ UINT32_C(0x2000)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of RX rings) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_RX_ASSETS_TEST \
+ UINT32_C(0x4000)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of CMPL rings) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_CMPL_ASSETS_TEST \
+ UINT32_C(0x8000)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of RSS ctx) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_RSSCOS_CTX_ASSETS_TEST \
+ UINT32_C(0x10000)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of ring groups) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_RING_GRP_ASSETS_TEST \
+ UINT32_C(0x20000)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of stat ctx) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_STAT_CTX_ASSETS_TEST \
+ UINT32_C(0x40000)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of VNICs) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_VNIC_ASSETS_TEST \
+ UINT32_C(0x80000)
+ /*
+ * This bit requests that the firmware test to see if all the assets
+ * requested in this command (i.e. number of L2 ctx) are available.
+ * The firmware will return an error if the requested assets are
+ * not available. The firwmare will NOT reserve the assets if they
+ * are available.
+ */
+ #define HWRM_FUNC_CFG_INPUT_FLAGS_L2_CTX_ASSETS_TEST \
+ UINT32_C(0x100000)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the mtu field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_MTU \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the mru field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_MRU \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the num_rsscos_ctxs field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the num_cmpl_rings field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the num_tx_rings field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the num_rx_rings field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the num_l2_ctxs field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the num_vnics field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the num_stat_ctxs field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the dflt_mac_addr field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the dflt_vlan field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN \
+ UINT32_C(0x400)
+ /*
+ * This bit must be '1' for the dflt_ip_addr field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_IP_ADDR \
+ UINT32_C(0x800)
+ /*
+ * This bit must be '1' for the min_bw field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_MIN_BW \
+ UINT32_C(0x1000)
+ /*
+ * This bit must be '1' for the max_bw field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW \
+ UINT32_C(0x2000)
+ /*
+ * This bit must be '1' for the async_event_cr field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR \
+ UINT32_C(0x4000)
+ /*
+ * This bit must be '1' for the vlan_antispoof_mode field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_VLAN_ANTISPOOF_MODE \
+ UINT32_C(0x8000)
+ /*
+ * This bit must be '1' for the allowed_vlan_pris field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_ALLOWED_VLAN_PRIS \
+ UINT32_C(0x10000)
+ /*
+ * This bit must be '1' for the evb_mode field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE \
+ UINT32_C(0x20000)
+ /*
+ * This bit must be '1' for the num_mcast_filters field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_MCAST_FILTERS \
+ UINT32_C(0x40000)
+ /*
+ * This bit must be '1' for the num_hw_ring_grps field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS \
+ UINT32_C(0x80000)
+ /*
+ * This bit must be '1' for the cache_linesize field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_CACHE_LINESIZE \
+ UINT32_C(0x100000)
+ /*
+ * This bit must be '1' for the num_msix field to be
+ * configured.
+ */
+ #define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_MSIX \
+ UINT32_C(0x200000)
+ /*
+ * The maximum transmission unit of the function.
+ * The HWRM should make sure that the mtu of
+ * the function does not exceed the mtu of the physical
+ * port that this function is associated with.
+ *
+ * In addition to configuring mtu per function, it is
+ * possible to configure mtu per transmit ring.
+ * By default, the mtu of each transmit ring associated
+ * with a function is equal to the mtu of the function.
+ * The HWRM should make sure that the mtu of each transmit
+ * ring that is assigned to a function has a valid mtu.
+ */
+ uint16_t mtu;
+ /*
+ * The maximum receive unit of the function.
+ * The HWRM should make sure that the mru of
+ * the function does not exceed the mru of the physical
+ * port that this function is associated with.
+ *
+ * In addition to configuring mru per function, it is
+ * possible to configure mru per vnic.
+ * By default, the mru of each vnic associated
+ * with a function is equal to the mru of the function.
+ * The HWRM should make sure that the mru of each vnic
+ * that is assigned to a function has a valid mru.
+ */
+ uint16_t mru;
+ /*
+ * The number of RSS/COS contexts requested for the
+ * function.
+ */
+ uint16_t num_rsscos_ctxs;
+ /*
+ * The number of completion rings requested for the
+ * function. This does not include the rings allocated
+ * to any children functions if any.
+ */
+ uint16_t num_cmpl_rings;
+ /*
+ * The number of transmit rings requested for the function.
+ * This does not include the rings allocated to any
+ * children functions if any.
+ */
+ uint16_t num_tx_rings;
+ /*
+ * The number of receive rings requested for the function.
+ * This does not include the rings allocated
+ * to any children functions if any.
+ */
+ uint16_t num_rx_rings;
+ /* The requested number of L2 contexts for the function. */
+ uint16_t num_l2_ctxs;
+ /* The requested number of vnics for the function. */
+ uint16_t num_vnics;
+ /* The requested number of statistic contexts for the function. */
+ uint16_t num_stat_ctxs;
+ /*
+ * The number of HW ring groups that should
+ * be reserved for this function.
+ */
+ uint16_t num_hw_ring_grps;
+ /* The default MAC address for the function being configured. */
+ uint8_t dflt_mac_addr[6];
+ /*
+ * The default VLAN for the function being configured.
+ * This field's format is same as 802.1Q Tag's
+ * Tag Control Information (TCI) format that includes both
+ * Priority Code Point (PCP) and VLAN Identifier (VID).
+ */
+ uint16_t dflt_vlan;
+ /*
+ * The default IP address for the function being configured.
+ * This address is only used in enabling source property check.
+ */
+ uint32_t dflt_ip_addr[4];
+ /*
+ * Minimum BW allocated for this function.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for the scheduler inside the device.
+ */
+ uint32_t min_bw;
+ /* The bandwidth value. */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_SFT 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_LAST \
+ HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_SFT 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated for this function.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for the scheduler inside the device.
+ */
+ uint32_t max_bw;
+ /* The bandwidth value. */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_SFT 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_LAST \
+ HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_SFT 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * ID of the target completion ring for receiving asynchronous
+ * event completions. If this field is not valid, then the
+ * HWRM shall use the default completion ring of the function
+ * that is being configured as the target completion ring for
+ * providing any asynchronous event completions for that
+ * function.
+ * If this field is valid, then the HWRM shall use the
+ * completion ring identified by this ID as the target
+ * completion ring for providing any asynchronous event
+ * completions for the function that is being configured.
+ */
+ uint16_t async_event_cr;
+ /* VLAN Anti-spoofing mode. */
+ uint8_t vlan_antispoof_mode;
+ /* No VLAN anti-spoofing checks are enabled */
+ #define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_NOCHECK \
+ UINT32_C(0x0)
+ /* Validate VLAN against the configured VLAN(s) */
+ #define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_VALIDATE_VLAN \
+ UINT32_C(0x1)
+ /* Insert VLAN if it does not exist, otherwise discard */
+ #define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_IF_VLANDNE \
+ UINT32_C(0x2)
+ /* Insert VLAN if it does not exist, override VLAN if it exists */
+ #define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_OR_OVERRIDE_VLAN \
+ UINT32_C(0x3)
+ #define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_LAST \
+ HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_OR_OVERRIDE_VLAN
+ /*
+ * This bit field defines VLAN PRIs that are allowed on
+ * this function.
+ * If nth bit is set, then VLAN PRI n is allowed on this
+ * function.
+ */
+ uint8_t allowed_vlan_pris;
+ /*
+ * The HWRM shall allow a PF driver to change EVB mode for the
+ * partition it belongs to.
+ * The HWRM shall not allow a VF driver to change the EVB mode.
+ * The HWRM shall take into account the switching of EVB mode
+ * from one to another and reconfigure hardware resources as
+ * appropriately.
+ * The switching from VEB to VEPA mode requires
+ * the disabling of the loopback traffic. Additionally,
+ * source knock outs are handled differently in VEB and VEPA
+ * modes.
+ */
+ uint8_t evb_mode;
+ /* No Edge Virtual Bridging (EVB) */
+ #define HWRM_FUNC_CFG_INPUT_EVB_MODE_NO_EVB UINT32_C(0x0)
+ /* Virtual Ethernet Bridge (VEB) */
+ #define HWRM_FUNC_CFG_INPUT_EVB_MODE_VEB UINT32_C(0x1)
+ /* Virtual Ethernet Port Aggregator (VEPA) */
+ #define HWRM_FUNC_CFG_INPUT_EVB_MODE_VEPA UINT32_C(0x2)
+ #define HWRM_FUNC_CFG_INPUT_EVB_MODE_LAST \
+ HWRM_FUNC_CFG_INPUT_EVB_MODE_VEPA
+ uint8_t options;
+ /*
+ * This value indicates the PCIE device cache line size.
+ * The cache line size allows the DMA writes to terminate and
+ * start at the cache boundary.
+ */
+ #define HWRM_FUNC_CFG_INPUT_OPTIONS_CACHE_LINESIZE_MASK \
+ UINT32_C(0x3)
+ #define HWRM_FUNC_CFG_INPUT_OPTIONS_CACHE_LINESIZE_SFT 0
+ /* Cache Line Size 64 bytes */
+ #define HWRM_FUNC_CFG_INPUT_OPTIONS_CACHE_LINESIZE_SIZE_64 \
+ UINT32_C(0x0)
+ /* Cache Line Size 128 bytes */
+ #define HWRM_FUNC_CFG_INPUT_OPTIONS_CACHE_LINESIZE_SIZE_128 \
+ UINT32_C(0x1)
+ #define HWRM_FUNC_CFG_INPUT_OPTIONS_CACHE_LINESIZE_LAST \
+ HWRM_FUNC_CFG_INPUT_OPTIONS_CACHE_LINESIZE_SIZE_128
+ /* Reserved for future. */
+ #define HWRM_FUNC_CFG_INPUT_OPTIONS_RSVD_MASK \
+ UINT32_C(0xfc)
+ #define HWRM_FUNC_CFG_INPUT_OPTIONS_RSVD_SFT 2
+ /*
+ * The number of multicast filters that should
+ * be reserved for this function on the RX side.
+ */
+ uint16_t num_mcast_filters;
+} __attribute__((packed));
+
+/* hwrm_func_cfg_output (size:128b/16B) */
+struct hwrm_func_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_qstats *
+ ********************/
+
+
+/* hwrm_func_qstats_input (size:192b/24B) */
+struct hwrm_func_qstats_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ 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;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_func_qstats_output (size:1408b/176B) */
+struct hwrm_func_qstats_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Number of transmitted unicast packets on the function. */
+ uint64_t tx_ucast_pkts;
+ /* Number of transmitted multicast packets on the function. */
+ uint64_t tx_mcast_pkts;
+ /* Number of transmitted broadcast packets on the function. */
+ uint64_t tx_bcast_pkts;
+ /*
+ * Number of transmitted packets that were discarded due to
+ * internal NIC resource problems. For transmit, this
+ * can only happen if TMP is configured to allow dropping
+ * in HOL blocking conditions, which is not a normal
+ * configuration.
+ */
+ uint64_t tx_discard_pkts;
+ /*
+ * Number of dropped packets on transmit path on the function.
+ * These are packets that have been marked for drop by
+ * the TE CFA block or are packets that exceeded the
+ * transmit MTU limit for the function.
+ */
+ uint64_t tx_drop_pkts;
+ /* Number of transmitted bytes for unicast traffic on the function. */
+ uint64_t tx_ucast_bytes;
+ /* Number of transmitted bytes for multicast traffic on the function. */
+ uint64_t tx_mcast_bytes;
+ /* Number of transmitted bytes for broadcast traffic on the function. */
+ uint64_t tx_bcast_bytes;
+ /* Number of received unicast packets on the function. */
+ uint64_t rx_ucast_pkts;
+ /* Number of received multicast packets on the function. */
+ uint64_t rx_mcast_pkts;
+ /* Number of received broadcast packets on the function. */
+ uint64_t rx_bcast_pkts;
+ /*
+ * Number of received packets that were discarded on the function
+ * due to resource limitations. This can happen for 3 reasons.
+ * # The BD used for the packet has a bad format.
+ * # There were no BDs available in the ring for the packet.
+ * # There were no BDs available on-chip for the packet.
+ */
+ uint64_t rx_discard_pkts;
+ /*
+ * Number of dropped packets on received path on the function.
+ * These are packets that have been marked for drop by the
+ * RE CFA.
+ */
+ uint64_t rx_drop_pkts;
+ /* Number of received bytes for unicast traffic on the function. */
+ uint64_t rx_ucast_bytes;
+ /* Number of received bytes for multicast traffic on the function. */
+ uint64_t rx_mcast_bytes;
+ /* Number of received bytes for broadcast traffic on the function. */
+ uint64_t rx_bcast_bytes;
+ /* Number of aggregated unicast packets on the function. */
+ uint64_t rx_agg_pkts;
+ /* Number of aggregated unicast bytes on the function. */
+ uint64_t rx_agg_bytes;
+ /* Number of aggregation events on the function. */
+ uint64_t rx_agg_events;
+ /* Number of aborted aggregations on the function. */
+ uint64_t rx_agg_aborts;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_clr_stats *
+ ***********************/
+
+
+/* hwrm_func_clr_stats_input (size:192b/24B) */
+struct hwrm_func_clr_stats_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * Function ID of the function.
+ * 0xFF... (All Fs) if the query is for the requesting
+ * function.
+ */
+ uint16_t fid;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_func_clr_stats_output (size:128b/16B) */
+struct hwrm_func_clr_stats_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_vf_resc_free *
+ **************************/
+
+
+/* hwrm_func_vf_resc_free_input (size:192b/24B) */
+struct hwrm_func_vf_resc_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This value is used to identify a Virtual Function (VF).
+ * The scope of VF ID is local within a PF.
+ */
+ uint16_t vf_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_func_vf_resc_free_output (size:128b/16B) */
+struct hwrm_func_vf_resc_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_vf_vnic_ids_query *
+ *******************************/
+
+
+/* hwrm_func_vf_vnic_ids_query_input (size:256b/32B) */
+struct hwrm_func_vf_vnic_ids_query_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This value is used to identify a Virtual Function (VF).
+ * The scope of VF ID is local within a PF.
+ */
+ uint16_t vf_id;
+ uint8_t unused_0[2];
+ /* Max number of vnic ids in vnic id table */
+ uint32_t max_vnic_id_cnt;
+ /* This is the address for VF VNIC ID table */
+ uint64_t vnic_id_tbl_addr;
+} __attribute__((packed));
+
+/* hwrm_func_vf_vnic_ids_query_output (size:128b/16B) */
+struct hwrm_func_vf_vnic_ids_query_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * Actual number of vnic ids
+ *
+ * Each VNIC ID is written as a 32-bit number.
+ */
+ uint32_t vnic_id_cnt;
+ uint8_t unused_0[3];
+ /*
+ * 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_func_drv_rgtr *
+ **********************/
+
+
+/* hwrm_func_drv_rgtr_input (size:896b/112B) */
+struct hwrm_func_drv_rgtr_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * When this bit is '1', the function driver is requesting
+ * all requests from its children VF drivers to be
+ * forwarded to itself.
+ * This flag can only be set by the PF driver.
+ * If a VF driver sets this flag, it should be ignored
+ * by the HWRM.
+ */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_ALL_MODE UINT32_C(0x1)
+ /*
+ * When this bit is '1', the function is requesting none of
+ * the requests from its children VF drivers to be
+ * forwarded to itself.
+ * This flag can only be set by the PF driver.
+ * If a VF driver sets this flag, it should be ignored
+ * by the HWRM.
+ */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_NONE_MODE UINT32_C(0x2)
+ /*
+ * When this bit is '1', then ver_maj_8b, ver_min_8b, ver_upd_8b
+ * fields shall be ignored and ver_maj, ver_min, ver_upd
+ * and ver_patch shall be used for the driver version information.
+ * When this bit is '0', then ver_maj_8b, ver_min_8b, ver_upd_8b
+ * fields shall be used for the driver version information and
+ * ver_maj, ver_min, ver_upd and ver_patch shall be ignored.
+ */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_16BIT_VER_MODE UINT32_C(0x4)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the os_type field to be
+ * configured.
+ */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_OS_TYPE \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the ver field to be
+ * configured.
+ */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the timestamp field to be
+ * configured.
+ */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_TIMESTAMP \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the vf_req_fwd field to be
+ * configured.
+ */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_REQ_FWD \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the async_event_fwd field to be
+ * configured.
+ */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD \
+ UINT32_C(0x10)
+ /* This value indicates the type of OS. The values are based on CIM_OperatingSystem.mof file as published by the DMTF. */
+ uint16_t os_type;
+ /* Unknown */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN UINT32_C(0x0)
+ /* Other OS not listed below. */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_OTHER UINT32_C(0x1)
+ /* MSDOS OS. */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_MSDOS UINT32_C(0xe)
+ /* Windows OS. */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WINDOWS UINT32_C(0x12)
+ /* Solaris OS. */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_SOLARIS UINT32_C(0x1d)
+ /* Linux OS. */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LINUX UINT32_C(0x24)
+ /* FreeBSD OS. */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD UINT32_C(0x2a)
+ /* VMware ESXi OS. */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_ESXI UINT32_C(0x68)
+ /* Microsoft Windows 8 64-bit OS. */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN864 UINT32_C(0x73)
+ /* Microsoft Windows Server 2012 R2 OS. */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN2012R2 UINT32_C(0x74)
+ /* UEFI driver. */
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UEFI UINT32_C(0x8000)
+ #define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LAST \
+ HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UEFI
+ /* This is the 8bit major version of the driver. */
+ uint8_t ver_maj_8b;
+ /* This is the 8bit minor version of the driver. */
+ uint8_t ver_min_8b;
+ /* This is the 8bit update version of the driver. */
+ uint8_t ver_upd_8b;
+ uint8_t unused_0[3];
+ /*
+ * This is a 32-bit timestamp provided by the driver for
+ * keep alive.
+ * The timestamp is in multiples of 1ms.
+ */
+ uint32_t timestamp;
+ uint8_t unused_1[4];
+ /*
+ * This is a 256-bit bit mask provided by the PF driver for
+ * letting the HWRM know what commands issued by the VF driver
+ * to the HWRM should be forwarded to the PF driver.
+ * Nth bit refers to the Nth req_type.
+ *
+ * Setting Nth bit to 1 indicates that requests from the
+ * VF driver with req_type equal to N shall be forwarded to
+ * the parent PF driver.
+ *
+ * This field is not valid for the VF driver.
+ */
+ uint32_t vf_req_fwd[8];
+ /*
+ * This is a 256-bit bit mask provided by the function driver
+ * (PF or VF driver) to indicate the list of asynchronous event
+ * completions to be forwarded.
+ *
+ * Nth bit refers to the Nth event_id.
+ *
+ * Setting Nth bit to 1 by the function driver shall result in
+ * the HWRM forwarding asynchronous event completion with
+ * event_id equal to N.
+ *
+ * If all bits are set to 0 (value of 0), then the HWRM shall
+ * not forward any asynchronous event completion to this
+ * function driver.
+ */
+ uint32_t async_event_fwd[8];
+ /* This is the 16bit major version of the driver. */
+ uint16_t ver_maj;
+ /* This is the 16bit minor version of the driver. */
+ uint16_t ver_min;
+ /* This is the 16bit update version of the driver. */
+ uint16_t ver_upd;
+ /* This is the 16bit patch version of the driver. */
+ uint16_t ver_patch;
+} __attribute__((packed));
+
+/* hwrm_func_drv_rgtr_output (size:128b/16B) */
+struct hwrm_func_drv_rgtr_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_drv_unrgtr *
+ ************************/
+
+
+/* hwrm_func_drv_unrgtr_input (size:192b/24B) */
+struct hwrm_func_drv_unrgtr_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * When this bit is '1', the function driver is notifying
+ * the HWRM to prepare for the shutdown.
+ */
+ #define HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN \
+ UINT32_C(0x1)
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_func_drv_unrgtr_output (size:128b/16B) */
+struct hwrm_func_drv_unrgtr_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_buf_rgtr *
+ **********************/
+
+
+/* hwrm_func_buf_rgtr_input (size:1024b/128B) */
+struct hwrm_func_buf_rgtr_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the vf_id field to be
+ * configured.
+ */
+ #define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_VF_ID UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the err_buf_addr field to be
+ * configured.
+ */
+ #define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_ERR_BUF_ADDR UINT32_C(0x2)
+ /*
+ * This value is used to identify a Virtual Function (VF).
+ * The scope of VF ID is local within a PF.
+ */
+ uint16_t vf_id;
+ /*
+ * This field represents the number of pages used for request
+ * buffer(s).
+ */
+ uint16_t req_buf_num_pages;
+ /*
+ * This field represents the page size used for request
+ * buffer(s).
+ */
+ uint16_t req_buf_page_size;
+ /* 16 bytes */
+ #define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_16B UINT32_C(0x4)
+ /* 4 Kbytes */
+ #define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_4K UINT32_C(0xc)
+ /* 8 Kbytes */
+ #define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_8K UINT32_C(0xd)
+ /* 64 Kbytes */
+ #define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_64K UINT32_C(0x10)
+ /* 2 Mbytes */
+ #define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_2M UINT32_C(0x15)
+ /* 4 Mbytes */
+ #define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_4M UINT32_C(0x16)
+ /* 1 Gbytes */
+ #define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_1G UINT32_C(0x1e)
+ #define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_LAST \
+ HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_1G
+ /* The length of the request buffer per VF in bytes. */
+ uint16_t req_buf_len;
+ /* The length of the response buffer in bytes. */
+ uint16_t resp_buf_len;
+ uint8_t unused_0[2];
+ /* This field represents the page address of page #0. */
+ uint64_t req_buf_page_addr0;
+ /* This field represents the page address of page #1. */
+ uint64_t req_buf_page_addr1;
+ /* This field represents the page address of page #2. */
+ uint64_t req_buf_page_addr2;
+ /* This field represents the page address of page #3. */
+ uint64_t req_buf_page_addr3;
+ /* This field represents the page address of page #4. */
+ uint64_t req_buf_page_addr4;
+ /* This field represents the page address of page #5. */
+ uint64_t req_buf_page_addr5;
+ /* This field represents the page address of page #6. */
+ uint64_t req_buf_page_addr6;
+ /* This field represents the page address of page #7. */
+ uint64_t req_buf_page_addr7;
+ /* This field represents the page address of page #8. */
+ uint64_t req_buf_page_addr8;
+ /* This field represents the page address of page #9. */
+ uint64_t req_buf_page_addr9;
+ /*
+ * This field is used to receive the error reporting from
+ * the chipset. Only applicable for PFs.
+ */
+ uint64_t error_buf_addr;
+ /*
+ * This field is used to receive the response forwarded by the
+ * HWRM.
+ */
+ uint64_t resp_buf_addr;
+} __attribute__((packed));
+
+/* hwrm_func_buf_rgtr_output (size:128b/16B) */
+struct hwrm_func_buf_rgtr_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_buf_unrgtr *
+ ************************/
+
+
+/* hwrm_func_buf_unrgtr_input (size:192b/24B) */
+struct hwrm_func_buf_unrgtr_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the vf_id field to be
+ * configured.
+ */
+ #define HWRM_FUNC_BUF_UNRGTR_INPUT_ENABLES_VF_ID UINT32_C(0x1)
+ /*
+ * This value is used to identify a Virtual Function (VF).
+ * The scope of VF ID is local within a PF.
+ */
+ uint16_t vf_id;
+ uint8_t unused_0[2];
+} __attribute__((packed));
+
+/* hwrm_func_buf_unrgtr_output (size:128b/16B) */
+struct hwrm_func_buf_unrgtr_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_drv_qver *
+ **********************/
+
+
+/* hwrm_func_drv_qver_input (size:192b/24B) */
+struct hwrm_func_drv_qver_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Reserved for future use. */
+ uint32_t reserved;
+ /*
+ * Function ID of the function that is being queried.
+ * 0xFF... (All Fs) if the query is for the requesting
+ * function.
+ */
+ uint16_t fid;
+ uint8_t unused_0[2];
+} __attribute__((packed));
+
+/* hwrm_func_drv_qver_output (size:192b/24B) */
+struct hwrm_func_drv_qver_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This value indicates the type of OS. The values are based on CIM_OperatingSystem.mof file as published by the DMTF. */
+ uint16_t os_type;
+ /* Unknown */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_UNKNOWN UINT32_C(0x0)
+ /* Other OS not listed below. */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_OTHER UINT32_C(0x1)
+ /* MSDOS OS. */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_MSDOS UINT32_C(0xe)
+ /* Windows OS. */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_WINDOWS UINT32_C(0x12)
+ /* Solaris OS. */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_SOLARIS UINT32_C(0x1d)
+ /* Linux OS. */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_LINUX UINT32_C(0x24)
+ /* FreeBSD OS. */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_FREEBSD UINT32_C(0x2a)
+ /* VMware ESXi OS. */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_ESXI UINT32_C(0x68)
+ /* Microsoft Windows 8 64-bit OS. */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_WIN864 UINT32_C(0x73)
+ /* Microsoft Windows Server 2012 R2 OS. */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_WIN2012R2 UINT32_C(0x74)
+ /* UEFI driver. */
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_UEFI UINT32_C(0x8000)
+ #define HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_LAST \
+ HWRM_FUNC_DRV_QVER_OUTPUT_OS_TYPE_UEFI
+ /* This is the 8bit major version of the driver. */
+ uint8_t ver_maj_8b;
+ /* This is the 8bit minor version of the driver. */
+ uint8_t ver_min_8b;
+ /* This is the 8bit update version of the driver. */
+ uint8_t ver_upd_8b;
+ uint8_t unused_0[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;
+ /* This is the 16bit major version of the driver. */
+ uint16_t ver_maj;
+ /* This is the 16bit minor version of the driver. */
+ uint16_t ver_min;
+ /* This is the 16bit update version of the driver. */
+ uint16_t ver_upd;
+ /* This is the 16bit patch version of the driver. */
+ uint16_t ver_patch;
+} __attribute__((packed));
+
+/****************************
+ * hwrm_func_resource_qcaps *
+ ****************************/
+
+
+/* hwrm_func_resource_qcaps_input (size:192b/24B) */
+struct hwrm_func_resource_qcaps_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ 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;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_func_resource_qcaps_output (size:448b/56B) */
+struct hwrm_func_resource_qcaps_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Maximum guaranteed number of VFs supported by PF. Not applicable for VFs. */
+ uint16_t max_vfs;
+ /* Maximum guaranteed number of MSI-X vectors supported by function */
+ uint16_t max_msix;
+ /* Hint of strategy to be used by PF driver to reserve resources for its VF */
+ uint16_t vf_reservation_strategy;
+ /* The PF driver should evenly divide its remaining resources among all VFs. */
+ #define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MAXIMAL \
+ UINT32_C(0x0)
+ /* The PF driver should only reserve minimal resources for each VF. */
+ #define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MINIMAL \
+ UINT32_C(0x1)
+ /*
+ * The PF driver should not reserve any resources for each VF until the
+ * the VF interface is brought up.
+ */
+ #define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MINIMAL_STATIC \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_LAST \
+ HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MINIMAL_STATIC
+ /* Minimum guaranteed number of RSS/COS contexts */
+ uint16_t min_rsscos_ctx;
+ /* Maximum non-guaranteed number of RSS/COS contexts */
+ uint16_t max_rsscos_ctx;
+ /* Minimum guaranteed number of completion rings */
+ uint16_t min_cmpl_rings;
+ /* Maximum non-guaranteed number of completion rings */
+ uint16_t max_cmpl_rings;
+ /* Minimum guaranteed number of transmit rings */
+ uint16_t min_tx_rings;
+ /* Maximum non-guaranteed number of transmit rings */
+ uint16_t max_tx_rings;
+ /* Minimum guaranteed number of receive rings */
+ uint16_t min_rx_rings;
+ /* Maximum non-guaranteed number of receive rings */
+ uint16_t max_rx_rings;
+ /* Minimum guaranteed number of L2 contexts */
+ uint16_t min_l2_ctxs;
+ /* Maximum non-guaranteed number of L2 contexts */
+ uint16_t max_l2_ctxs;
+ /* Minimum guaranteed number of VNICs */
+ uint16_t min_vnics;
+ /* Maximum non-guaranteed number of VNICs */
+ uint16_t max_vnics;
+ /* Minimum guaranteed number of statistic contexts */
+ uint16_t min_stat_ctx;
+ /* Maximum non-guaranteed number of statistic contexts */
+ uint16_t max_stat_ctx;
+ /* Minimum guaranteed number of ring groups */
+ uint16_t min_hw_ring_grps;
+ /* Maximum non-guaranteed number of ring groups */
+ uint16_t max_hw_ring_grps;
+ /*
+ * Maximum number of inputs into the transmit scheduler for this function.
+ * The number of TX rings assigned to the function cannot exceed this value.
+ */
+ uint16_t max_tx_scheduler_inputs;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_vf_resource_cfg *
+ *****************************/
+
+
+/* hwrm_func_vf_resource_cfg_input (size:448b/56B) */
+struct hwrm_func_vf_resource_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* VF ID that is being configured by PF */
+ uint16_t vf_id;
+ /* Maximum guaranteed number of MSI-X vectors for the function */
+ uint16_t max_msix;
+ /* Minimum guaranteed number of RSS/COS contexts */
+ uint16_t min_rsscos_ctx;
+ /* Maximum non-guaranteed number of RSS/COS contexts */
+ uint16_t max_rsscos_ctx;
+ /* Minimum guaranteed number of completion rings */
+ uint16_t min_cmpl_rings;
+ /* Maximum non-guaranteed number of completion rings */
+ uint16_t max_cmpl_rings;
+ /* Minimum guaranteed number of transmit rings */
+ uint16_t min_tx_rings;
+ /* Maximum non-guaranteed number of transmit rings */
+ uint16_t max_tx_rings;
+ /* Minimum guaranteed number of receive rings */
+ uint16_t min_rx_rings;
+ /* Maximum non-guaranteed number of receive rings */
+ uint16_t max_rx_rings;
+ /* Minimum guaranteed number of L2 contexts */
+ uint16_t min_l2_ctxs;
+ /* Maximum non-guaranteed number of L2 contexts */
+ uint16_t max_l2_ctxs;
+ /* Minimum guaranteed number of VNICs */
+ uint16_t min_vnics;
+ /* Maximum non-guaranteed number of VNICs */
+ uint16_t max_vnics;
+ /* Minimum guaranteed number of statistic contexts */
+ uint16_t min_stat_ctx;
+ /* Maximum non-guaranteed number of statistic contexts */
+ uint16_t max_stat_ctx;
+ /* Minimum guaranteed number of ring groups */
+ uint16_t min_hw_ring_grps;
+ /* Maximum non-guaranteed number of ring groups */
+ uint16_t max_hw_ring_grps;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_func_vf_resource_cfg_output (size:256b/32B) */
+struct hwrm_func_vf_resource_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Reserved number of RSS/COS contexts */
+ uint16_t reserved_rsscos_ctx;
+ /* Reserved number of completion rings */
+ uint16_t reserved_cmpl_rings;
+ /* Reserved number of transmit rings */
+ uint16_t reserved_tx_rings;
+ /* Reserved number of receive rings */
+ uint16_t reserved_rx_rings;
+ /* Reserved number of L2 contexts */
+ uint16_t reserved_l2_ctxs;
+ /* Reserved number of VNICs */
+ uint16_t reserved_vnics;
+ /* Reserved number of statistic contexts */
+ uint16_t reserved_stat_ctx;
+ /* Reserved number of ring groups */
+ uint16_t reserved_hw_ring_grps;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_backing_store_qcaps *
+ *********************************/
+
+
+/* hwrm_func_backing_store_qcaps_input (size:128b/16B) */
+struct hwrm_func_backing_store_qcaps_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+/* hwrm_func_backing_store_qcaps_output (size:512b/64B) */
+struct hwrm_func_backing_store_qcaps_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Maximum number of QP context entries supported for this function. */
+ uint32_t qp_max_entries;
+ /*
+ * Minimum number of QP context entries that are needed to be reserved
+ * for QP1 for the PF and its VFs. PF drivers must allocate at least
+ * this many QP context entries, even if RoCE will not be used.
+ */
+ uint16_t qp_min_qp1_entries;
+ /* Maximum number of QP context entries that can be used for L2. */
+ uint16_t qp_max_l2_entries;
+ /* Number of bytes that must be allocated for each context entry. */
+ uint16_t qp_entry_size;
+ /* Maximum number of SRQ context entries that can be used for L2. */
+ uint16_t srq_max_l2_entries;
+ /* Maximum number of SRQ context entries supported for this function. */
+ uint32_t srq_max_entries;
+ /* Number of bytes that must be allocated for each context entry. */
+ uint16_t srq_entry_size;
+ /* Maximum number of CQ context entries that can be used for L2. */
+ uint16_t cq_max_l2_entries;
+ /* Maximum number of CQ context entries supported for this function. */
+ uint32_t cq_max_entries;
+ /* Number of bytes that must be allocated for each context entry. */
+ uint16_t cq_entry_size;
+ /* Maximum number of VNIC context entries supported for this function. */
+ uint16_t vnic_max_vnic_entries;
+ /* Maximum number of Ring table context entries supported for this function. */
+ uint16_t vnic_max_ring_table_entries;
+ /* Number of bytes that must be allocated for each context entry. */
+ uint16_t vnic_entry_size;
+ /* Maximum number of statistic context entries supported for this function. */
+ uint32_t stat_max_entries;
+ /* Number of bytes that must be allocated for each context entry. */
+ uint16_t stat_entry_size;
+ /* Maximum number of TQM context entries supported per ring. */
+ uint16_t tqm_max_entries_per_ring;
+ /* Number of bytes that must be allocated for each context entry. */
+ uint16_t tqm_entry_size;
+ /* Number of bytes that must be allocated for each context entry. */
+ uint16_t mrav_entry_size;
+ /* Maximum number of MR/AV context entries supported for this function. */
+ uint32_t mrav_max_entries;
+ /* Maximum number of Timer context entries supported for this function. */
+ uint32_t tim_max_entries;
+ /* Number of bytes that must be allocated for each context entry. */
+ uint16_t tim_entry_size;
+ uint8_t unused_0;
+ /*
+ * 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_func_backing_store_cfg *
+ *******************************/
+
+
+/* hwrm_func_backing_store_cfg_input (size:2048b/256B) */
+struct hwrm_func_backing_store_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * When set, the firmware only uses on-chip resources and does not
+ * expect any backing store to be provided by the host driver. This
+ * mode provides minimal L2 functionality (e.g. limited L2 resources,
+ * no RoCE).
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_FLAGS_PREBOOT_MODE \
+ UINT32_C(0x1)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the qp fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_QP \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the srq fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_SRQ \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the cq fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_CQ \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the vnic fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_VNIC \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the stat fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_STAT \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the tqm_sp fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_SP \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the tqm_ring0 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING0 \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the tqm_ring1 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING1 \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the tqm_ring2 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING2 \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the tqm_ring3 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING3 \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the tqm_ring4 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING4 \
+ UINT32_C(0x400)
+ /*
+ * This bit must be '1' for the tqm_ring5 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING5 \
+ UINT32_C(0x800)
+ /*
+ * This bit must be '1' for the tqm_ring6 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING6 \
+ UINT32_C(0x1000)
+ /*
+ * This bit must be '1' for the tqm_ring7 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING7 \
+ UINT32_C(0x2000)
+ /*
+ * This bit must be '1' for the mrav fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_MRAV \
+ UINT32_C(0x4000)
+ /*
+ * This bit must be '1' for the tim fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TIM \
+ UINT32_C(0x8000)
+ /* QPC page size and level. */
+ uint8_t qpc_pg_size_qpc_lvl;
+ /* QPC PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_LVL_2
+ /* QPC page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_PG_SIZE_PG_1G
+ /* SRQ page size and level. */
+ uint8_t srq_pg_size_srq_lvl;
+ /* SRQ PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_LVL_LVL_2
+ /* SRQ page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_SRQ_PG_SIZE_PG_1G
+ /* CQ page size and level. */
+ uint8_t cq_pg_size_cq_lvl;
+ /* CQ PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_LVL_LVL_2
+ /* CQ page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_CQ_PG_SIZE_PG_1G
+ /* VNIC page size and level. */
+ uint8_t vnic_pg_size_vnic_lvl;
+ /* VNIC PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_LVL_LVL_2
+ /* VNIC page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_VNIC_PG_SIZE_PG_1G
+ /* Stat page size and level. */
+ uint8_t stat_pg_size_stat_lvl;
+ /* Stat PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_LVL_LVL_2
+ /* Stat page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_STAT_PG_SIZE_PG_1G
+ /* TQM slow path page size and level. */
+ uint8_t tqm_sp_pg_size_tqm_sp_lvl;
+ /* TQM slow path PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_LVL_LVL_2
+ /* TQM slow path page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_SP_PG_SIZE_PG_1G
+ /* TQM ring 0 page size and level. */
+ uint8_t tqm_ring0_pg_size_tqm_ring0_lvl;
+ /* TQM ring 0 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_LVL_LVL_2
+ /* TQM ring 0 page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING0_PG_SIZE_PG_1G
+ /* TQM ring 1 page size and level. */
+ uint8_t tqm_ring1_pg_size_tqm_ring1_lvl;
+ /* TQM ring 1 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_LVL_LVL_2
+ /* TQM ring 1 page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING1_PG_SIZE_PG_1G
+ /* TQM ring 2 page size and level. */
+ uint8_t tqm_ring2_pg_size_tqm_ring2_lvl;
+ /* TQM ring 2 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_LVL_LVL_2
+ /* TQM ring 2 page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING2_PG_SIZE_PG_1G
+ /* TQM ring 3 page size and level. */
+ uint8_t tqm_ring3_pg_size_tqm_ring3_lvl;
+ /* TQM ring 3 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_LVL_LVL_2
+ /* TQM ring 3 page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING3_PG_SIZE_PG_1G
+ /* TQM ring 4 page size and level. */
+ uint8_t tqm_ring4_pg_size_tqm_ring4_lvl;
+ /* TQM ring 4 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_LVL_LVL_2
+ /* TQM ring 4 page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING4_PG_SIZE_PG_1G
+ /* TQM ring 5 page size and level. */
+ uint8_t tqm_ring5_pg_size_tqm_ring5_lvl;
+ /* TQM ring 5 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_LVL_LVL_2
+ /* TQM ring 5 page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING5_PG_SIZE_PG_1G
+ /* TQM ring 6 page size and level. */
+ uint8_t tqm_ring6_pg_size_tqm_ring6_lvl;
+ /* TQM ring 6 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_LVL_LVL_2
+ /* TQM ring 6 page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING6_PG_SIZE_PG_1G
+ /* TQM ring 7 page size and level. */
+ uint8_t tqm_ring7_pg_size_tqm_ring7_lvl;
+ /* TQM ring 7 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_LVL_LVL_2
+ /* TQM ring 7 page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TQM_RING7_PG_SIZE_PG_1G
+ /* MR/AV page size and level. */
+ uint8_t mrav_pg_size_mrav_lvl;
+ /* MR/AV PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_LVL_LVL_2
+ /* MR/AV page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_MRAV_PG_SIZE_PG_1G
+ /* Timer page size and level. */
+ uint8_t tim_pg_size_tim_lvl;
+ /* Timer PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_LVL_LVL_2
+ /* Timer page size. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_CFG_INPUT_TIM_PG_SIZE_PG_1G
+ /* QP page directory. */
+ uint64_t qpc_page_dir;
+ /* SRQ page directory. */
+ uint64_t srq_page_dir;
+ /* CQ page directory. */
+ uint64_t cq_page_dir;
+ /* VNIC page directory. */
+ uint64_t vnic_page_dir;
+ /* Stat page directory. */
+ uint64_t stat_page_dir;
+ /* TQM slowpath page directory. */
+ uint64_t tqm_sp_page_dir;
+ /* TQM ring 0 page directory. */
+ uint64_t tqm_ring0_page_dir;
+ /* TQM ring 1 page directory. */
+ uint64_t tqm_ring1_page_dir;
+ /* TQM ring 2 page directory. */
+ uint64_t tqm_ring2_page_dir;
+ /* TQM ring 3 page directory. */
+ uint64_t tqm_ring3_page_dir;
+ /* TQM ring 4 page directory. */
+ uint64_t tqm_ring4_page_dir;
+ /* TQM ring 5 page directory. */
+ uint64_t tqm_ring5_page_dir;
+ /* TQM ring 6 page directory. */
+ uint64_t tqm_ring6_page_dir;
+ /* TQM ring 7 page directory. */
+ uint64_t tqm_ring7_page_dir;
+ /* MR/AV page directory. */
+ uint64_t mrav_page_dir;
+ /* Timer page directory. */
+ uint64_t tim_page_dir;
+ /* Number of QPs. */
+ uint32_t qp_num_entries;
+ /* Number of SRQs. */
+ uint32_t srq_num_entries;
+ /* Number of CQs. */
+ uint32_t cq_num_entries;
+ /* Number of Stats. */
+ uint32_t stat_num_entries;
+ /* Number of TQM slowpath entries. */
+ uint32_t tqm_sp_num_entries;
+ /* Number of TQM ring 0 entries. */
+ uint32_t tqm_ring0_num_entries;
+ /* Number of TQM ring 1 entries. */
+ uint32_t tqm_ring1_num_entries;
+ /* Number of TQM ring 2 entries. */
+ uint32_t tqm_ring2_num_entries;
+ /* Number of TQM ring 3 entries. */
+ uint32_t tqm_ring3_num_entries;
+ /* Number of TQM ring 4 entries. */
+ uint32_t tqm_ring4_num_entries;
+ /* Number of TQM ring 5 entries. */
+ uint32_t tqm_ring5_num_entries;
+ /* Number of TQM ring 6 entries. */
+ uint32_t tqm_ring6_num_entries;
+ /* Number of TQM ring 7 entries. */
+ uint32_t tqm_ring7_num_entries;
+ /* Number of MR/AV entries. */
+ uint32_t mrav_num_entries;
+ /* Number of Timer entries. */
+ uint32_t tim_num_entries;
+ /* Number of entries to reserve for QP1 */
+ uint16_t qp_num_qp1_entries;
+ /* Number of entries to reserve for L2 */
+ uint16_t qp_num_l2_entries;
+ /* Number of bytes that have been allocated for each context entry. */
+ uint16_t qp_entry_size;
+ /* Number of entries to reserve for L2 */
+ uint16_t srq_num_l2_entries;
+ /* Number of bytes that have been allocated for each context entry. */
+ uint16_t srq_entry_size;
+ /* Number of entries to reserve for L2 */
+ uint16_t cq_num_l2_entries;
+ /* Number of bytes that have been allocated for each context entry. */
+ uint16_t cq_entry_size;
+ /* Number of entries to reserve for VNIC entries */
+ uint16_t vnic_num_vnic_entries;
+ /* Number of entries to reserve for Ring table entries */
+ uint16_t vnic_num_ring_table_entries;
+ /* Number of bytes that have been allocated for each context entry. */
+ uint16_t vnic_entry_size;
+ /* Number of bytes that have been allocated for each context entry. */
+ uint16_t stat_entry_size;
+ /* Number of bytes that have been allocated for each context entry. */
+ uint16_t tqm_entry_size;
+ /* Number of bytes that have been allocated for each context entry. */
+ uint16_t mrav_entry_size;
+ /* Number of bytes that have been allocated for each context entry. */
+ uint16_t tim_entry_size;
+} __attribute__((packed));
+
+/* hwrm_func_backing_store_cfg_output (size:128b/16B) */
+struct hwrm_func_backing_store_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_func_backing_store_qcfg *
+ ********************************/
+
+
+/* hwrm_func_backing_store_qcfg_input (size:128b/16B) */
+struct hwrm_func_backing_store_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+/* hwrm_func_backing_store_qcfg_output (size:1920b/240B) */
+struct hwrm_func_backing_store_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint32_t flags;
+ /*
+ * When set, the firmware only uses on-chip resources and does not
+ * expect any backing store to be provided by the host driver. This
+ * mode provides minimal L2 functionality (e.g. limited L2 resources,
+ * no RoCE).
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_FLAGS_PREBOOT_MODE \
+ UINT32_C(0x1)
+ uint8_t unused_0[4];
+ /*
+ * This bit must be '1' for the qp fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_QP \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the srq fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_SRQ \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the cq fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_CQ \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the vnic fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_VNIC \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the stat fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_STAT \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the tqm_sp fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_TQM_SP \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the tqm_ring0 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_TQM_RING0 \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the tqm_ring1 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_TQM_RING1 \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the tqm_ring2 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_TQM_RING2 \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the tqm_ring3 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_TQM_RING3 \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the tqm_ring4 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_TQM_RING4 \
+ UINT32_C(0x400)
+ /*
+ * This bit must be '1' for the tqm_ring5 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_TQM_RING5 \
+ UINT32_C(0x800)
+ /*
+ * This bit must be '1' for the tqm_ring6 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_TQM_RING6 \
+ UINT32_C(0x1000)
+ /*
+ * This bit must be '1' for the tqm_ring7 fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_TQM_RING7 \
+ UINT32_C(0x2000)
+ /*
+ * This bit must be '1' for the mrav fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_MRAV \
+ UINT32_C(0x4000)
+ /*
+ * This bit must be '1' for the tim fields to be
+ * configured.
+ */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_UNUSED_0_TIM \
+ UINT32_C(0x8000)
+ /* QPC page size and level. */
+ uint8_t qpc_pg_size_qpc_lvl;
+ /* QPC PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_LVL_LVL_2
+ /* QPC page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_QPC_PG_SIZE_PG_1G
+ /* SRQ page size and level. */
+ uint8_t srq_pg_size_srq_lvl;
+ /* SRQ PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_LVL_LVL_2
+ /* SRQ page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_SRQ_PG_SIZE_PG_1G
+ /* CQ page size and level. */
+ uint8_t cq_pg_size_cq_lvl;
+ /* CQ PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_LVL_LVL_2
+ /* CQ page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_CQ_PG_SIZE_PG_1G
+ /* VNIC page size and level. */
+ uint8_t vnic_pg_size_vnic_lvl;
+ /* VNIC PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_LVL_LVL_2
+ /* VNIC page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_VNIC_PG_SIZE_PG_1G
+ /* Stat page size and level. */
+ uint8_t stat_pg_size_stat_lvl;
+ /* Stat PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_LVL_LVL_2
+ /* Stat page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_STAT_PG_SIZE_PG_1G
+ /* TQM slow path page size and level. */
+ uint8_t tqm_sp_pg_size_tqm_sp_lvl;
+ /* TQM slow path PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_LVL_LVL_2
+ /* TQM slow path page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_SP_PG_SIZE_PG_1G
+ /* TQM ring 0 page size and level. */
+ uint8_t tqm_ring0_pg_size_tqm_ring0_lvl;
+ /* TQM ring 0 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_LVL_LVL_2
+ /* TQM ring 0 page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING0_PG_SIZE_PG_1G
+ /* TQM ring 1 page size and level. */
+ uint8_t tqm_ring1_pg_size_tqm_ring1_lvl;
+ /* TQM ring 1 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_LVL_LVL_2
+ /* TQM ring 1 page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING1_PG_SIZE_PG_1G
+ /* TQM ring 2 page size and level. */
+ uint8_t tqm_ring2_pg_size_tqm_ring2_lvl;
+ /* TQM ring 2 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_LVL_LVL_2
+ /* TQM ring 2 page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING2_PG_SIZE_PG_1G
+ /* TQM ring 3 page size and level. */
+ uint8_t tqm_ring3_pg_size_tqm_ring3_lvl;
+ /* TQM ring 3 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_LVL_LVL_2
+ /* TQM ring 3 page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING3_PG_SIZE_PG_1G
+ /* TQM ring 4 page size and level. */
+ uint8_t tqm_ring4_pg_size_tqm_ring4_lvl;
+ /* TQM ring 4 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_LVL_LVL_2
+ /* TQM ring 4 page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING4_PG_SIZE_PG_1G
+ /* TQM ring 5 page size and level. */
+ uint8_t tqm_ring5_pg_size_tqm_ring5_lvl;
+ /* TQM ring 5 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_LVL_LVL_2
+ /* TQM ring 5 page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING5_PG_SIZE_PG_1G
+ /* TQM ring 6 page size and level. */
+ uint8_t tqm_ring6_pg_size_tqm_ring6_lvl;
+ /* TQM ring 6 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_LVL_LVL_2
+ /* TQM ring 6 page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING6_PG_SIZE_PG_1G
+ /* TQM ring 7 page size and level. */
+ uint8_t tqm_ring7_pg_size_tqm_ring7_lvl;
+ /* TQM ring 7 PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_LVL_LVL_2
+ /* TQM ring 7 page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TQM_RING7_PG_SIZE_PG_1G
+ /* MR/AV page size and level. */
+ uint8_t mrav_pg_size_mrav_lvl;
+ /* MR/AV PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_LVL_LVL_2
+ /* MR/AV page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_MRAV_PG_SIZE_PG_1G
+ /* Timer page size and level. */
+ uint8_t tim_pg_size_tim_lvl;
+ /* Timer PBL indirect levels. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_LVL_MASK \
+ UINT32_C(0xf)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_LVL_SFT 0
+ /* PBL pointer is physical start address. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_LVL_LVL_0 \
+ UINT32_C(0x0)
+ /* PBL pointer points to PTE table. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_LVL_LVL_1 \
+ UINT32_C(0x1)
+ /* PBL pointer points to PDE table with each entry pointing to PTE tables. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_LVL_LVL_2 \
+ UINT32_C(0x2)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_LVL_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_LVL_LVL_2
+ /* Timer page size. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_PG_SIZE_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_PG_SIZE_SFT 4
+ /* 4KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_PG_SIZE_PG_4K \
+ (UINT32_C(0x0) << 4)
+ /* 8KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_PG_SIZE_PG_8K \
+ (UINT32_C(0x1) << 4)
+ /* 64KB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_PG_SIZE_PG_64K \
+ (UINT32_C(0x2) << 4)
+ /* 2MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_PG_SIZE_PG_2M \
+ (UINT32_C(0x3) << 4)
+ /* 8MB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_PG_SIZE_PG_8M \
+ (UINT32_C(0x4) << 4)
+ /* 1GB. */
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_PG_SIZE_PG_1G \
+ (UINT32_C(0x5) << 4)
+ #define HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_PG_SIZE_LAST \
+ HWRM_FUNC_BACKING_STORE_QCFG_OUTPUT_TIM_PG_SIZE_PG_1G
+ /* QP page directory. */
+ uint64_t qpc_page_dir;
+ /* SRQ page directory. */
+ uint64_t srq_page_dir;
+ /* CQ page directory. */
+ uint64_t cq_page_dir;
+ /* VNIC page directory. */
+ uint64_t vnic_page_dir;
+ /* Stat page directory. */
+ uint64_t stat_page_dir;
+ /* TQM slowpath page directory. */
+ uint64_t tqm_sp_page_dir;
+ /* TQM ring 0 page directory. */
+ uint64_t tqm_ring0_page_dir;
+ /* TQM ring 1 page directory. */
+ uint64_t tqm_ring1_page_dir;
+ /* TQM ring 2 page directory. */
+ uint64_t tqm_ring2_page_dir;
+ /* TQM ring 3 page directory. */
+ uint64_t tqm_ring3_page_dir;
+ /* TQM ring 4 page directory. */
+ uint64_t tqm_ring4_page_dir;
+ /* TQM ring 5 page directory. */
+ uint64_t tqm_ring5_page_dir;
+ /* TQM ring 6 page directory. */
+ uint64_t tqm_ring6_page_dir;
+ /* TQM ring 7 page directory. */
+ uint64_t tqm_ring7_page_dir;
+ /* MR/AV page directory. */
+ uint64_t mrav_page_dir;
+ /* Timer page directory. */
+ uint64_t tim_page_dir;
+ /* Number of entries to reserve for QP1 */
+ uint16_t qp_num_qp1_entries;
+ /* Number of entries to reserve for L2 */
+ uint16_t qp_num_l2_entries;
+ /* Number of QPs. */
+ uint32_t qp_num_entries;
+ /* Number of SRQs. */
+ uint32_t srq_num_entries;
+ /* Number of entries to reserve for L2 */
+ uint16_t srq_num_l2_entries;
+ /* Number of entries to reserve for L2 */
+ uint16_t cq_num_l2_entries;
+ /* Number of CQs. */
+ uint32_t cq_num_entries;
+ /* Number of entries to reserve for VNIC entries */
+ uint16_t vnic_num_vnic_entries;
+ /* Number of entries to reserve for Ring table entries */
+ uint16_t vnic_num_ring_table_entries;
+ /* Number of Stats. */
+ uint32_t stat_num_entries;
+ /* Number of TQM slowpath entries. */
+ uint32_t tqm_sp_num_entries;
+ /* Number of TQM ring 0 entries. */
+ uint32_t tqm_ring0_num_entries;
+ /* Number of TQM ring 1 entries. */
+ uint32_t tqm_ring1_num_entries;
+ /* Number of TQM ring 2 entries. */
+ uint32_t tqm_ring2_num_entries;
+ /* Number of TQM ring 3 entries. */
+ uint32_t tqm_ring3_num_entries;
+ /* Number of TQM ring 4 entries. */
+ uint32_t tqm_ring4_num_entries;
+ /* Number of TQM ring 5 entries. */
+ uint32_t tqm_ring5_num_entries;
+ /* Number of TQM ring 6 entries. */
+ uint32_t tqm_ring6_num_entries;
+ /* Number of TQM ring 7 entries. */
+ uint32_t tqm_ring7_num_entries;
+ /* Number of MR/AV entries. */
+ uint32_t mrav_num_entries;
+ /* Number of Timer entries. */
+ uint32_t tim_num_entries;
+ uint8_t unused_1[7];
+ /*
+ * 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_port_phy_cfg *
+ *********************/
+
+
+/* hwrm_port_phy_cfg_input (size:448b/56B) */
+struct hwrm_port_phy_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * When this bit is set to '1', the PHY for the port shall
+ * be reset.
+ *
+ * # If this bit is set to 1, then the HWRM shall reset the
+ * PHY after applying PHY configuration changes specified
+ * in this command.
+ * # In order to guarantee that PHY configuration changes
+ * specified in this command take effect, the HWRM
+ * client should set this flag to 1.
+ * # If this bit is not set to 1, then the HWRM may reset
+ * the PHY depending on the current PHY configuration and
+ * settings specified in this command.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY \
+ UINT32_C(0x1)
+ /* deprecated bit. Do not use!!! */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_DEPRECATED \
+ UINT32_C(0x2)
+ /*
+ * When this bit is set to '1', the link shall be forced to
+ * the force_link_speed value.
+ *
+ * When this bit is set to '1', the HWRM client should
+ * not enable any of the auto negotiation related
+ * fields represented by auto_XXX fields in this command.
+ * When this bit is set to '1' and the HWRM client has
+ * enabled a auto_XXX field in this command, then the
+ * HWRM shall ignore the enabled auto_XXX field.
+ *
+ * When this bit is set to zero, the link
+ * shall be allowed to autoneg.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE \
+ UINT32_C(0x4)
+ /*
+ * When this bit is set to '1', the auto-negotiation process
+ * shall be restarted on the link.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG \
+ UINT32_C(0x8)
+ /*
+ * When this bit is set to '1', Energy Efficient Ethernet
+ * (EEE) is requested to be enabled on this link.
+ * If EEE is not supported on this port, then this flag
+ * shall be ignored by the HWRM.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_ENABLE \
+ UINT32_C(0x10)
+ /*
+ * When this bit is set to '1', Energy Efficient Ethernet
+ * (EEE) is requested to be disabled on this link.
+ * If EEE is not supported on this port, then this flag
+ * shall be ignored by the HWRM.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_DISABLE \
+ UINT32_C(0x20)
+ /*
+ * When this bit is set to '1' and EEE is enabled on this
+ * link, then TX LPI is requested to be enabled on the link.
+ * If EEE is not supported on this port, then this flag
+ * shall be ignored by the HWRM.
+ * If EEE is disabled on this port, then this flag shall be
+ * ignored by the HWRM.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI_ENABLE \
+ UINT32_C(0x40)
+ /*
+ * When this bit is set to '1' and EEE is enabled on this
+ * link, then TX LPI is requested to be disabled on the link.
+ * If EEE is not supported on this port, then this flag
+ * shall be ignored by the HWRM.
+ * If EEE is disabled on this port, then this flag shall be
+ * ignored by the HWRM.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI_DISABLE \
+ UINT32_C(0x80)
+ /*
+ * When set to 1, then the HWRM shall enable FEC autonegotitation
+ * on this port if supported.
+ * When set to 0, then this flag shall be ignored.
+ * If FEC autonegotiation is not supported, then the HWRM shall ignore this
+ * flag.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_ENABLE \
+ UINT32_C(0x100)
+ /*
+ * When set to 1, then the HWRM shall disable FEC autonegotiation
+ * on this port if supported.
+ * When set to 0, then this flag shall be ignored.
+ * If FEC autonegotiation is not supported, then the HWRM shall ignore this
+ * flag.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_DISABLE \
+ UINT32_C(0x200)
+ /*
+ * When set to 1, then the HWRM shall enable FEC CLAUSE 74 (Fire Code)
+ * on this port if supported.
+ * When set to 0, then this flag shall be ignored.
+ * If FEC CLAUSE 74 is not supported, then the HWRM shall ignore this
+ * flag.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_ENABLE \
+ UINT32_C(0x400)
+ /*
+ * When set to 1, then the HWRM shall disable FEC CLAUSE 74 (Fire Code)
+ * on this port if supported.
+ * When set to 0, then this flag shall be ignored.
+ * If FEC CLAUSE 74 is not supported, then the HWRM shall ignore this
+ * flag.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_DISABLE \
+ UINT32_C(0x800)
+ /*
+ * When set to 1, then the HWRM shall enable FEC CLAUSE 91 (Reed Solomon)
+ * on this port if supported.
+ * When set to 0, then this flag shall be ignored.
+ * If FEC CLAUSE 91 is not supported, then the HWRM shall ignore this
+ * flag.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_ENABLE \
+ UINT32_C(0x1000)
+ /*
+ * When set to 1, then the HWRM shall disable FEC CLAUSE 91 (Reed Solomon)
+ * on this port if supported.
+ * When set to 0, then this flag shall be ignored.
+ * If FEC CLAUSE 91 is not supported, then the HWRM shall ignore this
+ * flag.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_DISABLE \
+ UINT32_C(0x2000)
+ /*
+ * When this bit is set to '1', the link shall be forced to
+ * be taken down.
+ *
+ * # When this bit is set to '1", all other
+ * command input settings related to the link speed shall
+ * be ignored.
+ * Once the link state is forced down, it can be
+ * explicitly cleared from that state by setting this flag
+ * to '0'.
+ * # If this flag is set to '0', then the link shall be
+ * cleared from forced down state if the link is in forced
+ * down state.
+ * There may be conditions (e.g. out-of-band or sideband
+ * configuration changes for the link) outside the scope
+ * of the HWRM implementation that may clear forced down
+ * link state.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DWN \
+ UINT32_C(0x4000)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the auto_mode field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the auto_duplex field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the auto_pause field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the auto_link_speed field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the auto_link_speed_mask field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the wirespeed field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_WIRESPEED \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the lpbk field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_LPBK \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the preemphasis field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_PREEMPHASIS \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the force_pause field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the eee_link_speed_mask field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_EEE_LINK_SPEED_MASK \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the tx_lpi_timer field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_ENABLES_TX_LPI_TIMER \
+ UINT32_C(0x400)
+ /* Port ID of port that is to be configured. */
+ uint16_t port_id;
+ /*
+ * This is the speed that will be used if the force
+ * bit is '1'. If unsupported speed is selected, an error
+ * will be generated.
+ */
+ uint16_t force_link_speed;
+ /* 100Mb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100MB UINT32_C(0x1)
+ /* 1Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB UINT32_C(0xa)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2GB UINT32_C(0x14)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB UINT32_C(0x19)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB UINT32_C(0x64)
+ /* 20Mb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB UINT32_C(0xc8)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB UINT32_C(0xfa)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB UINT32_C(0x190)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB UINT32_C(0x1f4)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB UINT32_C(0x3e8)
+ /* 10Mb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB UINT32_C(0xffff)
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_LAST \
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB
+ /*
+ * This value is used to identify what autoneg mode is
+ * used when the link speed is not being forced.
+ */
+ uint8_t auto_mode;
+ /* Disable autoneg or autoneg disabled. No speeds are selected. */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE UINT32_C(0x0)
+ /* Select all possible speeds for autoneg mode. */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS UINT32_C(0x1)
+ /*
+ * Select only the auto_link_speed speed for autoneg mode. This mode has
+ * been DEPRECATED. An HWRM client should not use this mode.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_SPEED UINT32_C(0x2)
+ /*
+ * Select the auto_link_speed or any speed below that speed for autoneg.
+ * This mode has been DEPRECATED. An HWRM client should not use this mode.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW UINT32_C(0x3)
+ /*
+ * Select the speeds based on the corresponding link speed mask value
+ * that is provided.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK UINT32_C(0x4)
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_LAST \
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK
+ /*
+ * This is the duplex setting that will be used if the autoneg_mode
+ * is "one_speed" or "one_or_below".
+ */
+ uint8_t auto_duplex;
+ /* Half Duplex will be requested. */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF UINT32_C(0x0)
+ /* Full duplex will be requested. */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL UINT32_C(0x1)
+ /* Both Half and Full dupex will be requested. */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH UINT32_C(0x2)
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_LAST \
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH
+ /*
+ * This value is used to configure the pause that will be
+ * used for autonegotiation.
+ * Add text on the usage of auto_pause and force_pause.
+ */
+ uint8_t auto_pause;
+ /*
+ * When this bit is '1', Generation of tx pause messages
+ * has been requested. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', Reception of rx pause messages
+ * has been requested. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX \
+ UINT32_C(0x2)
+ /*
+ * When set to 1, the advertisement of pause is enabled.
+ *
+ * # When the auto_mode is not set to none and this flag is
+ * set to 1, then the auto_pause bits on this port are being
+ * advertised and autoneg pause results are being interpreted.
+ * # When the auto_mode is not set to none and this
+ * flag is set to 0, the pause is forced as indicated in
+ * force_pause, and also advertised as auto_pause bits, but
+ * the autoneg results are not interpreted since the pause
+ * configuration is being forced.
+ * # When the auto_mode is set to none and this flag is set to
+ * 1, auto_pause bits should be ignored and should be set to 0.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_AUTONEG_PAUSE \
+ UINT32_C(0x4)
+ uint8_t unused_0;
+ /*
+ * This is the speed that will be used if the autoneg_mode
+ * is "one_speed" or "one_or_below". If an unsupported speed
+ * is selected, an error will be generated.
+ */
+ uint16_t auto_link_speed;
+ /* 100Mb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100MB UINT32_C(0x1)
+ /* 1Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB UINT32_C(0xa)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2GB UINT32_C(0x14)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB UINT32_C(0x19)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10GB UINT32_C(0x64)
+ /* 20Mb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB UINT32_C(0xc8)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB UINT32_C(0xfa)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_40GB UINT32_C(0x190)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB UINT32_C(0x1f4)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100GB UINT32_C(0x3e8)
+ /* 10Mb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB UINT32_C(0xffff)
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_LAST \
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB
+ /*
+ * This is a mask of link speeds that will be used if
+ * autoneg_mode is "mask". If unsupported speed is enabled
+ * an error will be generated.
+ */
+ uint16_t auto_link_speed_mask;
+ /* 100Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MBHD \
+ UINT32_C(0x1)
+ /* 100Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB \
+ UINT32_C(0x2)
+ /* 1Gb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GBHD \
+ UINT32_C(0x4)
+ /* 1Gb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB \
+ UINT32_C(0x8)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2GB \
+ UINT32_C(0x10)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2_5GB \
+ UINT32_C(0x20)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB \
+ UINT32_C(0x40)
+ /* 20Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB \
+ UINT32_C(0x80)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB \
+ UINT32_C(0x100)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB \
+ UINT32_C(0x200)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB \
+ UINT32_C(0x400)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100GB \
+ UINT32_C(0x800)
+ /* 10Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10MBHD \
+ UINT32_C(0x1000)
+ /* 10Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10MB \
+ UINT32_C(0x2000)
+ /* This value controls the wirespeed feature. */
+ uint8_t wirespeed;
+ /* Wirespeed feature is disabled. */
+ #define HWRM_PORT_PHY_CFG_INPUT_WIRESPEED_OFF UINT32_C(0x0)
+ /* Wirespeed feature is enabled. */
+ #define HWRM_PORT_PHY_CFG_INPUT_WIRESPEED_ON UINT32_C(0x1)
+ #define HWRM_PORT_PHY_CFG_INPUT_WIRESPEED_LAST \
+ HWRM_PORT_PHY_CFG_INPUT_WIRESPEED_ON
+ /* This value controls the loopback setting for the PHY. */
+ uint8_t lpbk;
+ /* No loopback is selected. Normal operation. */
+ #define HWRM_PORT_PHY_CFG_INPUT_LPBK_NONE UINT32_C(0x0)
+ /*
+ * The HW will be configured with local loopback such that
+ * host data is sent back to the host without modification.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_LPBK_LOCAL UINT32_C(0x1)
+ /*
+ * The HW will be configured with remote loopback such that
+ * port logic will send packets back out the transmitter that
+ * are received.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_LPBK_REMOTE UINT32_C(0x2)
+ /*
+ * The HW will be configured with external loopback such that
+ * host data is sent on the trasmitter and based on the external
+ * loopback connection the data will be received without modification.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_LPBK_EXTERNAL UINT32_C(0x3)
+ #define HWRM_PORT_PHY_CFG_INPUT_LPBK_LAST \
+ HWRM_PORT_PHY_CFG_INPUT_LPBK_EXTERNAL
+ /*
+ * This value is used to configure the pause that will be
+ * used for force mode.
+ */
+ uint8_t force_pause;
+ /*
+ * When this bit is '1', Generation of tx pause messages
+ * is supported. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX UINT32_C(0x1)
+ /*
+ * When this bit is '1', Reception of rx pause messages
+ * is supported. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX UINT32_C(0x2)
+ uint8_t unused_1;
+ /*
+ * This value controls the pre-emphasis to be used for the
+ * link. Driver should not set this value (use
+ * enable.preemphasis = 0) unless driver is sure of setting.
+ * Normally HWRM FW will determine proper pre-emphasis.
+ */
+ uint32_t preemphasis;
+ /*
+ * Setting for link speed mask that is used to
+ * advertise speeds during autonegotiation when EEE is enabled.
+ * This field is valid only when EEE is enabled.
+ * The speeds specified in this field shall be a subset of
+ * speeds specified in auto_link_speed_mask.
+ * If EEE is enabled,then at least one speed shall be provided
+ * in this mask.
+ */
+ uint16_t eee_link_speed_mask;
+ /* Reserved */
+ #define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD1 \
+ UINT32_C(0x1)
+ /* 100Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_100MB \
+ UINT32_C(0x2)
+ /* Reserved */
+ #define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD2 \
+ UINT32_C(0x4)
+ /* 1Gb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_1GB \
+ UINT32_C(0x8)
+ /* Reserved */
+ #define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD3 \
+ UINT32_C(0x10)
+ /* Reserved */
+ #define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD4 \
+ UINT32_C(0x20)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_10GB \
+ UINT32_C(0x40)
+ uint8_t unused_2[2];
+ /*
+ * Reuested setting of TX LPI timer in microseconds.
+ * This field is valid only when EEE is enabled and TX LPI is
+ * enabled.
+ */
+ uint32_t tx_lpi_timer;
+ #define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_MASK UINT32_C(0xffffff)
+ #define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_SFT 0
+ uint32_t unused_3;
+} __attribute__((packed));
+
+/* hwrm_port_phy_cfg_output (size:128b/16B) */
+struct hwrm_port_phy_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_port_phy_cfg_cmd_err (size:64b/8B) */
+struct hwrm_port_phy_cfg_cmd_err {
+ /*
+ * command specific error codes that goes to
+ * the cmd_err field in Common HWRM Error Response.
+ */
+ uint8_t code;
+ /* Unknown error */
+ #define HWRM_PORT_PHY_CFG_CMD_ERR_CODE_UNKNOWN UINT32_C(0x0)
+ /* Unable to complete operation due to invalid speed */
+ #define HWRM_PORT_PHY_CFG_CMD_ERR_CODE_ILLEGAL_SPEED UINT32_C(0x1)
+ /*
+ * retry the command since the phy is not ready.
+ * retry count is returned in opaque_0.
+ * This is only valid for the first command and
+ * this value will not change for successive calls.
+ * but if a 0 is returned at any time then this should
+ * be treated as an un recoverable failure,
+ *
+ * retry interval in milli seconds is returned in opaque_1.
+ * This specifies the time that user should wait before
+ * issuing the next port_phy_cfg command.
+ */
+ #define HWRM_PORT_PHY_CFG_CMD_ERR_CODE_RETRY UINT32_C(0x2)
+ #define HWRM_PORT_PHY_CFG_CMD_ERR_CODE_LAST \
+ HWRM_PORT_PHY_CFG_CMD_ERR_CODE_RETRY
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/**********************
+ * hwrm_port_phy_qcfg *
+ **********************/
+
+
+/* hwrm_port_phy_qcfg_input (size:192b/24B) */
+struct hwrm_port_phy_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Port ID of port that is to be queried. */
+ uint16_t port_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_port_phy_qcfg_output (size:768b/96B) */
+struct hwrm_port_phy_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This value indicates the current link status. */
+ uint8_t link;
+ /* There is no link or cable detected. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_NO_LINK UINT32_C(0x0)
+ /* There is no link, but a cable has been detected. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL UINT32_C(0x1)
+ /* There is a link. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK UINT32_C(0x2)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK
+ uint8_t unused_0;
+ /* This value indicates the current link speed of the connection. */
+ uint16_t link_speed;
+ /* 100Mb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB UINT32_C(0x1)
+ /* 1Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB UINT32_C(0xa)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB UINT32_C(0x14)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB UINT32_C(0x19)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB UINT32_C(0x64)
+ /* 20Mb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB UINT32_C(0xc8)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB UINT32_C(0xfa)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB UINT32_C(0x190)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB UINT32_C(0x1f4)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB UINT32_C(0x3e8)
+ /* 10Mb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB UINT32_C(0xffff)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB
+ /*
+ * This value is indicates the duplex of the current
+ * configuration.
+ */
+ uint8_t duplex_cfg;
+ /* Half Duplex connection. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_CFG_HALF UINT32_C(0x0)
+ /* Full duplex connection. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_CFG_FULL UINT32_C(0x1)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_CFG_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_CFG_FULL
+ /*
+ * This value is used to indicate the current
+ * pause configuration. When autoneg is enabled, this value
+ * represents the autoneg results of pause configuration.
+ */
+ uint8_t pause;
+ /*
+ * When this bit is '1', Generation of tx pause messages
+ * is supported. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX UINT32_C(0x1)
+ /*
+ * When this bit is '1', Reception of rx pause messages
+ * is supported. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX UINT32_C(0x2)
+ /*
+ * The supported speeds for the port. This is a bit mask.
+ * For each speed that is supported, the corrresponding
+ * bit will be set to '1'.
+ */
+ uint16_t support_speeds;
+ /* 100Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MBHD \
+ UINT32_C(0x1)
+ /* 100Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MB \
+ UINT32_C(0x2)
+ /* 1Gb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GBHD \
+ UINT32_C(0x4)
+ /* 1Gb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB \
+ UINT32_C(0x8)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2GB \
+ UINT32_C(0x10)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB \
+ UINT32_C(0x20)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB \
+ UINT32_C(0x40)
+ /* 20Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB \
+ UINT32_C(0x80)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB \
+ UINT32_C(0x100)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB \
+ UINT32_C(0x200)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB \
+ UINT32_C(0x400)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB \
+ UINT32_C(0x800)
+ /* 10Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10MBHD \
+ UINT32_C(0x1000)
+ /* 10Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10MB \
+ UINT32_C(0x2000)
+ /*
+ * Current setting of forced link speed.
+ * When the link speed is not being forced, this
+ * value shall be set to 0.
+ */
+ uint16_t force_link_speed;
+ /* 100Mb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100MB UINT32_C(0x1)
+ /* 1Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB UINT32_C(0xa)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB UINT32_C(0x14)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB UINT32_C(0x19)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB UINT32_C(0x64)
+ /* 20Mb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB UINT32_C(0xc8)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB UINT32_C(0xfa)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB \
+ UINT32_C(0x190)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB \
+ UINT32_C(0x1f4)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB \
+ UINT32_C(0x3e8)
+ /* 10Mb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB \
+ UINT32_C(0xffff)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB
+ /* Current setting of auto negotiation mode. */
+ uint8_t auto_mode;
+ /* Disable autoneg or autoneg disabled. No speeds are selected. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE UINT32_C(0x0)
+ /* Select all possible speeds for autoneg mode. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ALL_SPEEDS UINT32_C(0x1)
+ /*
+ * Select only the auto_link_speed speed for autoneg mode. This mode has
+ * been DEPRECATED. An HWRM client should not use this mode.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_SPEED UINT32_C(0x2)
+ /*
+ * Select the auto_link_speed or any speed below that speed for autoneg.
+ * This mode has been DEPRECATED. An HWRM client should not use this mode.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_OR_BELOW UINT32_C(0x3)
+ /*
+ * Select the speeds based on the corresponding link speed mask value
+ * that is provided.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_SPEED_MASK UINT32_C(0x4)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_SPEED_MASK
+ /*
+ * Current setting of pause autonegotiation.
+ * Move autoneg_pause flag here.
+ */
+ uint8_t auto_pause;
+ /*
+ * When this bit is '1', Generation of tx pause messages
+ * has been requested. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_TX \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', Reception of rx pause messages
+ * has been requested. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_RX \
+ UINT32_C(0x2)
+ /*
+ * When set to 1, the advertisement of pause is enabled.
+ *
+ * # When the auto_mode is not set to none and this flag is
+ * set to 1, then the auto_pause bits on this port are being
+ * advertised and autoneg pause results are being interpreted.
+ * # When the auto_mode is not set to none and this
+ * flag is set to 0, the pause is forced as indicated in
+ * force_pause, and also advertised as auto_pause bits, but
+ * the autoneg results are not interpreted since the pause
+ * configuration is being forced.
+ * # When the auto_mode is set to none and this flag is set to
+ * 1, auto_pause bits should be ignored and should be set to 0.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_AUTONEG_PAUSE \
+ UINT32_C(0x4)
+ /*
+ * Current setting for auto_link_speed. This field is only
+ * valid when auto_mode is set to "one_speed" or "one_or_below".
+ */
+ uint16_t auto_link_speed;
+ /* 100Mb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100MB UINT32_C(0x1)
+ /* 1Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_1GB UINT32_C(0xa)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2GB UINT32_C(0x14)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB UINT32_C(0x19)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10GB UINT32_C(0x64)
+ /* 20Mb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_20GB UINT32_C(0xc8)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_25GB UINT32_C(0xfa)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB UINT32_C(0x190)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB UINT32_C(0x1f4)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB UINT32_C(0x3e8)
+ /* 10Mb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB \
+ UINT32_C(0xffff)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB
+ /*
+ * Current setting for auto_link_speed_mask that is used to
+ * advertise speeds during autonegotiation.
+ * This field is only valid when auto_mode is set to "mask".
+ * The speeds specified in this field shall be a subset of
+ * supported speeds on this port.
+ */
+ uint16_t auto_link_speed_mask;
+ /* 100Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100MBHD \
+ UINT32_C(0x1)
+ /* 100Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100MB \
+ UINT32_C(0x2)
+ /* 1Gb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_1GBHD \
+ UINT32_C(0x4)
+ /* 1Gb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_1GB \
+ UINT32_C(0x8)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_2GB \
+ UINT32_C(0x10)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_2_5GB \
+ UINT32_C(0x20)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10GB \
+ UINT32_C(0x40)
+ /* 20Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_20GB \
+ UINT32_C(0x80)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_25GB \
+ UINT32_C(0x100)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_40GB \
+ UINT32_C(0x200)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_50GB \
+ UINT32_C(0x400)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100GB \
+ UINT32_C(0x800)
+ /* 10Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10MBHD \
+ UINT32_C(0x1000)
+ /* 10Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10MB \
+ UINT32_C(0x2000)
+ /* Current setting for wirespeed. */
+ uint8_t wirespeed;
+ /* Wirespeed feature is disabled. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_WIRESPEED_OFF UINT32_C(0x0)
+ /* Wirespeed feature is enabled. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_WIRESPEED_ON UINT32_C(0x1)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_WIRESPEED_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_WIRESPEED_ON
+ /* Current setting for loopback. */
+ uint8_t lpbk;
+ /* No loopback is selected. Normal operation. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_NONE UINT32_C(0x0)
+ /*
+ * The HW will be configured with local loopback such that
+ * host data is sent back to the host without modification.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_LOCAL UINT32_C(0x1)
+ /*
+ * The HW will be configured with remote loopback such that
+ * port logic will send packets back out the transmitter that
+ * are received.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_REMOTE UINT32_C(0x2)
+ /*
+ * The HW will be configured with external loopback such that
+ * host data is sent on the trasmitter and based on the external
+ * loopback connection the data will be received without modification.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_EXTERNAL UINT32_C(0x3)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_EXTERNAL
+ /*
+ * Current setting of forced pause.
+ * When the pause configuration is not being forced, then
+ * this value shall be set to 0.
+ */
+ uint8_t force_pause;
+ /*
+ * When this bit is '1', Generation of tx pause messages
+ * is supported. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_TX UINT32_C(0x1)
+ /*
+ * When this bit is '1', Reception of rx pause messages
+ * is supported. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_RX UINT32_C(0x2)
+ /*
+ * This value indicates the current status of the optics module on
+ * this port.
+ */
+ uint8_t module_status;
+ /* Module is inserted and accepted */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NONE \
+ UINT32_C(0x0)
+ /* Module is rejected and transmit side Laser is disabled. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX \
+ UINT32_C(0x1)
+ /* Module mismatch warning. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG \
+ UINT32_C(0x2)
+ /* Module is rejected and powered down. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN \
+ UINT32_C(0x3)
+ /* Module is not inserted. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED \
+ UINT32_C(0x4)
+ /* Module status is not applicable. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE \
+ UINT32_C(0xff)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE
+ /* Current setting for preemphasis. */
+ uint32_t preemphasis;
+ /* This field represents the major version of the PHY. */
+ uint8_t phy_maj;
+ /* This field represents the minor version of the PHY. */
+ uint8_t phy_min;
+ /* This field represents the build version of the PHY. */
+ uint8_t phy_bld;
+ /* This value represents a PHY type. */
+ uint8_t phy_type;
+ /* Unknown */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN \
+ UINT32_C(0x0)
+ /* BASE-CR */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR \
+ UINT32_C(0x1)
+ /* BASE-KR4 (Deprecated) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4 \
+ UINT32_C(0x2)
+ /* BASE-LR */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR \
+ UINT32_C(0x3)
+ /* BASE-SR */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR \
+ UINT32_C(0x4)
+ /* BASE-KR2 (Deprecated) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2 \
+ UINT32_C(0x5)
+ /* BASE-KX */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX \
+ UINT32_C(0x6)
+ /* BASE-KR */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR \
+ UINT32_C(0x7)
+ /* BASE-T */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET \
+ UINT32_C(0x8)
+ /* EEE capable BASE-T */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE \
+ UINT32_C(0x9)
+ /* SGMII connected external PHY */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY \
+ UINT32_C(0xa)
+ /* 25G_BASECR_CA_L */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_L \
+ UINT32_C(0xb)
+ /* 25G_BASECR_CA_S */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_S \
+ UINT32_C(0xc)
+ /* 25G_BASECR_CA_N */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_N \
+ UINT32_C(0xd)
+ /* 25G_BASESR */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASESR \
+ UINT32_C(0xe)
+ /* 100G_BASECR4 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR4 \
+ UINT32_C(0xf)
+ /* 100G_BASESR4 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR4 \
+ UINT32_C(0x10)
+ /* 100G_BASELR4 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR4 \
+ UINT32_C(0x11)
+ /* 100G_BASEER4 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER4 \
+ UINT32_C(0x12)
+ /* 100G_BASESR10 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR10 \
+ UINT32_C(0x13)
+ /* 40G_BASECR4 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASECR4 \
+ UINT32_C(0x14)
+ /* 40G_BASESR4 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASESR4 \
+ UINT32_C(0x15)
+ /* 40G_BASELR4 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASELR4 \
+ UINT32_C(0x16)
+ /* 40G_BASEER4 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASEER4 \
+ UINT32_C(0x17)
+ /* 40G_ACTIVE_CABLE */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_ACTIVE_CABLE \
+ UINT32_C(0x18)
+ /* 1G_baseT */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASET \
+ UINT32_C(0x19)
+ /* 1G_baseSX */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASESX \
+ UINT32_C(0x1a)
+ /* 1G_baseCX */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASECX \
+ UINT32_C(0x1b)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASECX
+ /* This value represents a media type. */
+ uint8_t media_type;
+ /* Unknown */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_UNKNOWN UINT32_C(0x0)
+ /* Twisted Pair */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP UINT32_C(0x1)
+ /* Direct Attached Copper */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC UINT32_C(0x2)
+ /* Fiber */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE UINT32_C(0x3)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE
+ /* This value represents a transceiver type. */
+ uint8_t xcvr_pkg_type;
+ /* PHY and MAC are in the same package */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_INTERNAL \
+ UINT32_C(0x1)
+ /* PHY and MAC are in different packages */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL \
+ UINT32_C(0x2)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL
+ uint8_t eee_config_phy_addr;
+ /* This field represents PHY address. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_MASK \
+ UINT32_C(0x1f)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_SFT 0
+ /*
+ * This field represents flags related to EEE configuration.
+ * These EEE configuration flags are valid only when the
+ * auto_mode is not set to none (in other words autonegotiation
+ * is enabled).
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_MASK \
+ UINT32_C(0xe0)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_SFT 5
+ /*
+ * When set to 1, Energy Efficient Ethernet (EEE) mode is enabled.
+ * Speeds for autoneg with EEE mode enabled
+ * are based on eee_link_speed_mask.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ENABLED \
+ UINT32_C(0x20)
+ /*
+ * This flag is valid only when eee_enabled is set to 1.
+ *
+ * # If eee_enabled is set to 0, then EEE mode is disabled
+ * and this flag shall be ignored.
+ * # If eee_enabled is set to 1 and this flag is set to 1,
+ * then Energy Efficient Ethernet (EEE) mode is enabled
+ * and in use.
+ * # If eee_enabled is set to 1 and this flag is set to 0,
+ * then Energy Efficient Ethernet (EEE) mode is enabled
+ * but is currently not in use.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ACTIVE \
+ UINT32_C(0x40)
+ /*
+ * This flag is valid only when eee_enabled is set to 1.
+ *
+ * # If eee_enabled is set to 0, then EEE mode is disabled
+ * and this flag shall be ignored.
+ * # If eee_enabled is set to 1 and this flag is set to 1,
+ * then Energy Efficient Ethernet (EEE) mode is enabled
+ * and TX LPI is enabled.
+ * # If eee_enabled is set to 1 and this flag is set to 0,
+ * then Energy Efficient Ethernet (EEE) mode is enabled
+ * but TX LPI is disabled.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_TX_LPI \
+ UINT32_C(0x80)
+ /*
+ * When set to 1, the parallel detection is used to determine
+ * the speed of the link partner.
+ *
+ * Parallel detection is used when a autonegotiation capable
+ * device is connected to a link parter that is not capable
+ * of autonegotiation.
+ */
+ uint8_t parallel_detect;
+ /*
+ * When set to 1, the parallel detection is used to determine
+ * the speed of the link partner.
+ *
+ * Parallel detection is used when a autonegotiation capable
+ * device is connected to a link parter that is not capable
+ * of autonegotiation.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_PARALLEL_DETECT UINT32_C(0x1)
+ /*
+ * The advertised speeds for the port by the link partner.
+ * Each advertised speed will be set to '1'.
+ */
+ uint16_t link_partner_adv_speeds;
+ /* 100Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MBHD \
+ UINT32_C(0x1)
+ /* 100Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MB \
+ UINT32_C(0x2)
+ /* 1Gb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GBHD \
+ UINT32_C(0x4)
+ /* 1Gb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GB \
+ UINT32_C(0x8)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2GB \
+ UINT32_C(0x10)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2_5GB \
+ UINT32_C(0x20)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10GB \
+ UINT32_C(0x40)
+ /* 20Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_20GB \
+ UINT32_C(0x80)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_25GB \
+ UINT32_C(0x100)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_40GB \
+ UINT32_C(0x200)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_50GB \
+ UINT32_C(0x400)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100GB \
+ UINT32_C(0x800)
+ /* 10Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10MBHD \
+ UINT32_C(0x1000)
+ /* 10Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10MB \
+ UINT32_C(0x2000)
+ /*
+ * The advertised autoneg for the port by the link partner.
+ * This field is deprecated and should be set to 0.
+ */
+ uint8_t link_partner_adv_auto_mode;
+ /* Disable autoneg or autoneg disabled. No speeds are selected. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_NONE \
+ UINT32_C(0x0)
+ /* Select all possible speeds for autoneg mode. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS \
+ UINT32_C(0x1)
+ /*
+ * Select only the auto_link_speed speed for autoneg mode. This mode has
+ * been DEPRECATED. An HWRM client should not use this mode.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_SPEED \
+ UINT32_C(0x2)
+ /*
+ * Select the auto_link_speed or any speed below that speed for autoneg.
+ * This mode has been DEPRECATED. An HWRM client should not use this mode.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_OR_BELOW \
+ UINT32_C(0x3)
+ /*
+ * Select the speeds based on the corresponding link speed mask value
+ * that is provided.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_SPEED_MASK \
+ UINT32_C(0x4)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_SPEED_MASK
+ /* The advertised pause settings on the port by the link partner. */
+ uint8_t link_partner_adv_pause;
+ /*
+ * When this bit is '1', Generation of tx pause messages
+ * is supported. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_TX \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', Reception of rx pause messages
+ * is supported. Disabled otherwise.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_RX \
+ UINT32_C(0x2)
+ /*
+ * Current setting for link speed mask that is used to
+ * advertise speeds during autonegotiation when EEE is enabled.
+ * This field is valid only when eee_enabled flags is set to 1.
+ * The speeds specified in this field shall be a subset of
+ * speeds specified in auto_link_speed_mask.
+ */
+ uint16_t adv_eee_link_speed_mask;
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD1 \
+ UINT32_C(0x1)
+ /* 100Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_100MB \
+ UINT32_C(0x2)
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD2 \
+ UINT32_C(0x4)
+ /* 1Gb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_1GB \
+ UINT32_C(0x8)
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD3 \
+ UINT32_C(0x10)
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD4 \
+ UINT32_C(0x20)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_10GB \
+ UINT32_C(0x40)
+ /*
+ * Current setting for link speed mask that is advertised by
+ * the link partner when EEE is enabled.
+ * This field is valid only when eee_enabled flags is set to 1.
+ */
+ uint16_t link_partner_adv_eee_link_speed_mask;
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD1 \
+ UINT32_C(0x1)
+ /* 100Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_100MB \
+ UINT32_C(0x2)
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD2 \
+ UINT32_C(0x4)
+ /* 1Gb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_1GB \
+ UINT32_C(0x8)
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD3 \
+ UINT32_C(0x10)
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD4 \
+ UINT32_C(0x20)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_10GB \
+ UINT32_C(0x40)
+ uint32_t xcvr_identifier_type_tx_lpi_timer;
+ /*
+ * Current setting of TX LPI timer in microseconds.
+ * This field is valid only when_eee_enabled flag is set to 1
+ * and tx_lpi_enabled is set to 1.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_TX_LPI_TIMER_MASK \
+ UINT32_C(0xffffff)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_TX_LPI_TIMER_SFT 0
+ /* This value represents transceiver identifier type. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_MASK \
+ UINT32_C(0xff000000)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_SFT 24
+ /* Unknown */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_UNKNOWN \
+ (UINT32_C(0x0) << 24)
+ /* SFP/SFP+/SFP28 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_SFP \
+ (UINT32_C(0x3) << 24)
+ /* QSFP+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP \
+ (UINT32_C(0xc) << 24)
+ /* QSFP+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPPLUS \
+ (UINT32_C(0xd) << 24)
+ /* QSFP28 */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28 \
+ (UINT32_C(0x11) << 24)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28
+ /*
+ * This value represents the current configuration of
+ * Forward Error Correction (FEC) on the port.
+ */
+ uint16_t fec_cfg;
+ /*
+ * When set to 1, then FEC is not supported on this port. If this flag
+ * is set to 1, then all other FEC configuration flags shall be ignored.
+ * When set to 0, then FEC is supported as indicated by other
+ * configuration flags.
+ * If no cable is attached and the HWRM does not yet know the FEC
+ * capability, then the HWRM shall set this flag to 1 when reporting
+ * FEC capability.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_NONE_SUPPORTED \
+ UINT32_C(0x1)
+ /*
+ * When set to 1, then FEC autonegotiation is supported on this port.
+ * When set to 0, then FEC autonegotiation is not supported on this port.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * When set to 1, then FEC autonegotiation is enabled on this port.
+ * When set to 0, then FEC autonegotiation is disabled if supported.
+ * This flag should be ignored if FEC autonegotiation is not supported on this port.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_ENABLED \
+ UINT32_C(0x4)
+ /*
+ * When set to 1, then FEC CLAUSE 74 (Fire Code) is supported on this port.
+ * When set to 0, then FEC CLAUSE 74 (Fire Code) is not supported on this port.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_SUPPORTED \
+ UINT32_C(0x8)
+ /*
+ * When set to 1, then FEC CLAUSE 74 (Fire Code) is enabled on this port.
+ * When set to 0, then FEC CLAUSE 74 (Fire Code) is disabled if supported.
+ * This flag should be ignored if FEC CLAUSE 74 is not supported on this port.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_ENABLED \
+ UINT32_C(0x10)
+ /*
+ * When set to 1, then FEC CLAUSE 91 (Reed Solomon) is supported on this port.
+ * When set to 0, then FEC CLAUSE 91 (Reed Solomon) is not supported on this port.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_SUPPORTED \
+ UINT32_C(0x20)
+ /*
+ * When set to 1, then FEC CLAUSE 91 (Reed Solomon) is enabled on this port.
+ * When set to 0, then FEC CLAUSE 91 (Reed Solomon) is disabled if supported.
+ * This flag should be ignored if FEC CLAUSE 91 is not supported on this port.
+ */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_ENABLED \
+ UINT32_C(0x40)
+ /*
+ * This value is indicates the duplex of the current
+ * connection state.
+ */
+ uint8_t duplex_state;
+ /* Half Duplex connection. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_STATE_HALF UINT32_C(0x0)
+ /* Full duplex connection. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_STATE_FULL UINT32_C(0x1)
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_STATE_LAST \
+ HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_STATE_FULL
+ /* Option flags fields. */
+ uint8_t option_flags;
+ /* When this bit is '1', Media auto detect is enabled. */
+ #define HWRM_PORT_PHY_QCFG_OUTPUT_OPTION_FLAGS_MEDIA_AUTO_DETECT \
+ UINT32_C(0x1)
+ /*
+ * Up to 16 bytes of null padded ASCII string representing
+ * PHY vendor.
+ * If the string is set to null, then the vendor name is not
+ * available.
+ */
+ char phy_vendor_name[16];
+ /*
+ * Up to 16 bytes of null padded ASCII string that
+ * identifies vendor specific part number of the PHY.
+ * If the string is set to null, then the vendor specific
+ * part number is not available.
+ */
+ char phy_vendor_partnumber[16];
+ uint8_t unused_2[7];
+ /*
+ * 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_port_mac_cfg *
+ *********************/
+
+
+/* hwrm_port_mac_cfg_input (size:320b/40B) */
+struct hwrm_port_mac_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * In this field, there are a number of CoS mappings related flags
+ * that are used to configure CoS mappings and their corresponding
+ * priorities in the hardware.
+ * For the priorities of CoS mappings, the HWRM uses the following
+ * priority order (high to low) by default:
+ * # vlan pri
+ * # ip_dscp
+ * # tunnel_vlan_pri
+ * # default cos
+ *
+ * A subset of CoS mappings can be enabled.
+ * If a priority is not specified for an enabled CoS mapping, the
+ * priority will be assigned in the above order for the enabled CoS
+ * mappings. For example, if vlan_pri and ip_dscp CoS mappings are
+ * enabled and their priorities are not specified, the following
+ * priority order (high to low) will be used by the HWRM:
+ * # vlan_pri
+ * # ip_dscp
+ * # default cos
+ *
+ * vlan_pri CoS mapping together with default CoS with lower priority
+ * are enabled by default by the HWRM.
+ */
+ uint32_t flags;
+ /*
+ * When this bit is '1', this command will configure
+ * the MAC to match the current link state of the PHY.
+ * If the link is not established on the PHY, then this
+ * bit has no effect.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_MATCH_LINK \
+ UINT32_C(0x1)
+ /*
+ * When this bit is set to '1', the inner VLAN PRI to CoS mapping
+ * is requested to be enabled.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_VLAN_PRI2COS_ENABLE \
+ UINT32_C(0x2)
+ /*
+ * When this bit is set to '1', tunnel VLAN PRI field to
+ * CoS mapping is requested to be enabled.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_TUNNEL_PRI2COS_ENABLE \
+ UINT32_C(0x4)
+ /*
+ * When this bit is set to '1', the IP DSCP to CoS mapping is
+ * requested to be enabled.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_IP_DSCP2COS_ENABLE \
+ UINT32_C(0x8)
+ /*
+ * When this bit is '1', the HWRM is requested to
+ * enable timestamp capture capability on the receive side
+ * of this port.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_PTP_RX_TS_CAPTURE_ENABLE \
+ UINT32_C(0x10)
+ /*
+ * When this bit is '1', the HWRM is requested to
+ * disable timestamp capture capability on the receive side
+ * of this port.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_PTP_RX_TS_CAPTURE_DISABLE \
+ UINT32_C(0x20)
+ /*
+ * When this bit is '1', the HWRM is requested to
+ * enable timestamp capture capability on the transmit side
+ * of this port.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_PTP_TX_TS_CAPTURE_ENABLE \
+ UINT32_C(0x40)
+ /*
+ * When this bit is '1', the HWRM is requested to
+ * disable timestamp capture capability on the transmit side
+ * of this port.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_PTP_TX_TS_CAPTURE_DISABLE \
+ UINT32_C(0x80)
+ /*
+ * When this bit is '1', the Out-Of-Box WoL is requested to
+ * be enabled on this port.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_OOB_WOL_ENABLE \
+ UINT32_C(0x100)
+ /*
+ * When this bit is '1', the the Out-Of-Box WoL is requested to
+ * be disabled on this port.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_OOB_WOL_DISABLE \
+ UINT32_C(0x200)
+ /*
+ * When this bit is set to '1', the inner VLAN PRI to CoS mapping
+ * is requested to be disabled.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_VLAN_PRI2COS_DISABLE \
+ UINT32_C(0x400)
+ /*
+ * When this bit is set to '1', tunnel VLAN PRI field to
+ * CoS mapping is requested to be disabled.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_TUNNEL_PRI2COS_DISABLE \
+ UINT32_C(0x800)
+ /*
+ * When this bit is set to '1', the IP DSCP to CoS mapping is
+ * requested to be disabled.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_FLAGS_IP_DSCP2COS_DISABLE \
+ UINT32_C(0x1000)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the ipg field to be
+ * configured.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_ENABLES_IPG \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the lpbk field to be
+ * configured.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_ENABLES_LPBK \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the vlan_pri2cos_map_pri field to be
+ * configured.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_ENABLES_VLAN_PRI2COS_MAP_PRI \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the tunnel_pri2cos_map_pri field to be
+ * configured.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_ENABLES_TUNNEL_PRI2COS_MAP_PRI \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the dscp2cos_map_pri field to be
+ * configured.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_ENABLES_DSCP2COS_MAP_PRI \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the rx_ts_capture_ptp_msg_type field to be
+ * configured.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the tx_ts_capture_ptp_msg_type field to be
+ * configured.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_ENABLES_TX_TS_CAPTURE_PTP_MSG_TYPE \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the cos_field_cfg field to be
+ * configured.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_ENABLES_COS_FIELD_CFG \
+ UINT32_C(0x100)
+ /* Port ID of port that is to be configured. */
+ uint16_t port_id;
+ /*
+ * This value is used to configure the minimum IPG that will
+ * be sent between packets by this port.
+ */
+ uint8_t ipg;
+ /* This value controls the loopback setting for the MAC. */
+ uint8_t lpbk;
+ /* No loopback is selected. Normal operation. */
+ #define HWRM_PORT_MAC_CFG_INPUT_LPBK_NONE UINT32_C(0x0)
+ /*
+ * The HW will be configured with local loopback such that
+ * host data is sent back to the host without modification.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_LPBK_LOCAL UINT32_C(0x1)
+ /*
+ * The HW will be configured with remote loopback such that
+ * port logic will send packets back out the transmitter that
+ * are received.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_LPBK_REMOTE UINT32_C(0x2)
+ #define HWRM_PORT_MAC_CFG_INPUT_LPBK_LAST \
+ HWRM_PORT_MAC_CFG_INPUT_LPBK_REMOTE
+ /*
+ * This value controls the priority setting of VLAN PRI to CoS
+ * mapping based on VLAN Tags of inner packet headers of
+ * tunneled packets or packet headers of non-tunneled packets.
+ *
+ * # Each XXX_pri variable shall have a unique priority value
+ * when it is being specified.
+ * # When comparing priorities of mappings, higher value
+ * indicates higher priority.
+ * For example, a value of 0-3 is returned where 0 is being
+ * the lowest priority and 3 is being the highest priority.
+ */
+ uint8_t vlan_pri2cos_map_pri;
+ /* Reserved field. */
+ uint8_t reserved1;
+ /*
+ * This value controls the priority setting of VLAN PRI to CoS
+ * mapping based on VLAN Tags of tunneled header.
+ * This mapping only applies when tunneled headers
+ * are present.
+ *
+ * # Each XXX_pri variable shall have a unique priority value
+ * when it is being specified.
+ * # When comparing priorities of mappings, higher value
+ * indicates higher priority.
+ * For example, a value of 0-3 is returned where 0 is being
+ * the lowest priority and 3 is being the highest priority.
+ */
+ uint8_t tunnel_pri2cos_map_pri;
+ /*
+ * This value controls the priority setting of IP DSCP to CoS
+ * mapping based on inner IP header of tunneled packets or
+ * IP header of non-tunneled packets.
+ *
+ * # Each XXX_pri variable shall have a unique priority value
+ * when it is being specified.
+ * # When comparing priorities of mappings, higher value
+ * indicates higher priority.
+ * For example, a value of 0-3 is returned where 0 is being
+ * the lowest priority and 3 is being the highest priority.
+ */
+ uint8_t dscp2pri_map_pri;
+ /*
+ * This is a 16-bit bit mask that is used to request a
+ * specific configuration of time stamp capture of PTP messages
+ * on the receive side of this port.
+ * This field shall be ignored if the ptp_rx_ts_capture_enable
+ * flag is not set in this command.
+ * Otherwise, if bit 'i' is set, then the HWRM is being
+ * requested to configure the receive side of the port to
+ * capture the time stamp of every received PTP message
+ * with messageType field value set to i.
+ */
+ uint16_t rx_ts_capture_ptp_msg_type;
+ /*
+ * This is a 16-bit bit mask that is used to request a
+ * specific configuration of time stamp capture of PTP messages
+ * on the transmit side of this port.
+ * This field shall be ignored if the ptp_tx_ts_capture_enable
+ * flag is not set in this command.
+ * Otherwise, if bit 'i' is set, then the HWRM is being
+ * requested to configure the transmit sied of the port to
+ * capture the time stamp of every transmitted PTP message
+ * with messageType field value set to i.
+ */
+ uint16_t tx_ts_capture_ptp_msg_type;
+ /* Configuration of CoS fields. */
+ uint8_t cos_field_cfg;
+ /* Reserved */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_RSVD1 \
+ UINT32_C(0x1)
+ /*
+ * This field is used to specify selection of VLAN PRI value
+ * based on whether one or two VLAN Tags are present in
+ * the inner packet headers of tunneled packets or
+ * non-tunneled packets.
+ * This field is valid only if inner VLAN PRI to CoS mapping
+ * is enabled.
+ * If VLAN PRI to CoS mapping is not enabled, then this
+ * field shall be ignored.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_VLAN_PRI_SEL_MASK \
+ UINT32_C(0x6)
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_VLAN_PRI_SEL_SFT \
+ 1
+ /*
+ * Select inner VLAN PRI when 1 or 2 VLAN Tags are
+ * present in the inner packet headers
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_VLAN_PRI_SEL_INNERMOST \
+ (UINT32_C(0x0) << 1)
+ /*
+ * Select outer VLAN Tag PRI when 2 VLAN Tags are
+ * present in the inner packet headers.
+ * No VLAN PRI shall be selected for this configuration
+ * if only one VLAN Tag is present in the inner
+ * packet headers.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_VLAN_PRI_SEL_OUTER \
+ (UINT32_C(0x1) << 1)
+ /*
+ * Select outermost VLAN PRI when 1 or 2 VLAN Tags
+ * are present in the inner packet headers
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_VLAN_PRI_SEL_OUTERMOST \
+ (UINT32_C(0x2) << 1)
+ /* Unspecified */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_VLAN_PRI_SEL_UNSPECIFIED \
+ (UINT32_C(0x3) << 1)
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_VLAN_PRI_SEL_LAST \
+ HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_VLAN_PRI_SEL_UNSPECIFIED
+ /*
+ * This field is used to specify selection of tunnel VLAN
+ * PRI value based on whether one or two VLAN Tags are
+ * present in tunnel headers.
+ * This field is valid only if tunnel VLAN PRI to CoS mapping
+ * is enabled.
+ * If tunnel VLAN PRI to CoS mapping is not enabled, then this
+ * field shall be ignored.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_MASK \
+ UINT32_C(0x18)
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_SFT \
+ 3
+ /*
+ * Select inner VLAN PRI when 1 or 2 VLAN Tags are
+ * present in the tunnel packet headers
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_INNERMOST \
+ (UINT32_C(0x0) << 3)
+ /*
+ * Select outer VLAN Tag PRI when 2 VLAN Tags are
+ * present in the tunnel packet headers.
+ * No tunnel VLAN PRI shall be selected for this
+ * configuration if only one VLAN Tag is present in
+ * the tunnel packet headers.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_OUTER \
+ (UINT32_C(0x1) << 3)
+ /*
+ * Select outermost VLAN PRI when 1 or 2 VLAN Tags
+ * are present in the tunnel packet headers
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_OUTERMOST \
+ (UINT32_C(0x2) << 3)
+ /* Unspecified */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_UNSPECIFIED \
+ (UINT32_C(0x3) << 3)
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_LAST \
+ HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_UNSPECIFIED
+ /*
+ * This field shall be used to provide default CoS value
+ * that has been configured on this port.
+ * This field is valid only if default CoS mapping
+ * is enabled.
+ * If default CoS mapping is not enabled, then this
+ * field shall be ignored.
+ */
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_DEFAULT_COS_MASK \
+ UINT32_C(0xe0)
+ #define HWRM_PORT_MAC_CFG_INPUT_COS_FIELD_CFG_DEFAULT_COS_SFT \
+ 5
+ uint8_t unused_0[3];
+} __attribute__((packed));
+
+/* hwrm_port_mac_cfg_output (size:128b/16B) */
+struct hwrm_port_mac_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * This is the configured maximum length of Ethernet packet
+ * payload that is allowed to be received on the port.
+ * This value does not include the number of bytes used by
+ * Ethernet header and trailer (CRC).
+ */
+ uint16_t mru;
+ /*
+ * This is the configured maximum length of Ethernet packet
+ * payload that is allowed to be transmitted on the port.
+ * This value does not include the number of bytes used by
+ * Ethernet header and trailer (CRC).
+ */
+ uint16_t mtu;
+ /* Current configuration of the IPG value. */
+ uint8_t ipg;
+ /* Current value of the loopback value. */
+ uint8_t lpbk;
+ /* No loopback is selected. Normal operation. */
+ #define HWRM_PORT_MAC_CFG_OUTPUT_LPBK_NONE UINT32_C(0x0)
+ /*
+ * The HW will be configured with local loopback such that
+ * host data is sent back to the host without modification.
+ */
+ #define HWRM_PORT_MAC_CFG_OUTPUT_LPBK_LOCAL UINT32_C(0x1)
+ /*
+ * The HW will be configured with remote loopback such that
+ * port logic will send packets back out the transmitter that
+ * are received.
+ */
+ #define HWRM_PORT_MAC_CFG_OUTPUT_LPBK_REMOTE UINT32_C(0x2)
+ #define HWRM_PORT_MAC_CFG_OUTPUT_LPBK_LAST \
+ HWRM_PORT_MAC_CFG_OUTPUT_LPBK_REMOTE
+ uint8_t unused_0;
+ /*
+ * 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_port_mac_qcfg *
+ **********************/
+
+
+/* hwrm_port_mac_qcfg_input (size:192b/24B) */
+struct hwrm_port_mac_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Port ID of port that is to be configured. */
+ uint16_t port_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_port_mac_qcfg_output (size:192b/24B) */
+struct hwrm_port_mac_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * This is the configured maximum length of Ethernet packet
+ * payload that is allowed to be received on the port.
+ * This value does not include the number of bytes used by the
+ * Ethernet header and trailer (CRC).
+ */
+ uint16_t mru;
+ /*
+ * This is the configured maximum length of Ethernet packet
+ * payload that is allowed to be transmitted on the port.
+ * This value does not include the number of bytes used by the
+ * Ethernet header and trailer (CRC).
+ */
+ uint16_t mtu;
+ /*
+ * The minimum IPG that will
+ * be sent between packets by this port.
+ */
+ uint8_t ipg;
+ /* The loopback setting for the MAC. */
+ uint8_t lpbk;
+ /* No loopback is selected. Normal operation. */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_LPBK_NONE UINT32_C(0x0)
+ /*
+ * The HW will be configured with local loopback such that
+ * host data is sent back to the host without modification.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_LPBK_LOCAL UINT32_C(0x1)
+ /*
+ * The HW will be configured with remote loopback such that
+ * port logic will send packets back out the transmitter that
+ * are received.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_LPBK_REMOTE UINT32_C(0x2)
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_LPBK_LAST \
+ HWRM_PORT_MAC_QCFG_OUTPUT_LPBK_REMOTE
+ /*
+ * Priority setting for VLAN PRI to CoS mapping.
+ * # Each XXX_pri variable shall have a unique priority value
+ * when it is being used.
+ * # When comparing priorities of mappings, higher value
+ * indicates higher priority.
+ * For example, a value of 0-3 is returned where 0 is being
+ * the lowest priority and 3 is being the highest priority.
+ * # If the correspoding CoS mapping is not enabled, then this
+ * field should be ignored.
+ * # This value indicates the normalized priority value retained
+ * in the HWRM.
+ */
+ uint8_t vlan_pri2cos_map_pri;
+ /*
+ * In this field, a number of CoS mappings related flags
+ * are used to indicate configured CoS mappings.
+ */
+ uint8_t flags;
+ /*
+ * When this bit is set to '1', the inner VLAN PRI to CoS mapping
+ * is enabled.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_FLAGS_VLAN_PRI2COS_ENABLE \
+ UINT32_C(0x1)
+ /*
+ * When this bit is set to '1', tunnel VLAN PRI field to
+ * CoS mapping is enabled.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_FLAGS_TUNNEL_PRI2COS_ENABLE \
+ UINT32_C(0x2)
+ /*
+ * When this bit is set to '1', the IP DSCP to CoS mapping is
+ * enabled.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_FLAGS_IP_DSCP2COS_ENABLE \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', the Out-Of-Box WoL is enabled on this
+ * port.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_FLAGS_OOB_WOL_ENABLE \
+ UINT32_C(0x8)
+ /* When this bit is '1', PTP is enabled for RX on this port. */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_FLAGS_PTP_RX_TS_CAPTURE_ENABLE \
+ UINT32_C(0x10)
+ /* When this bit is '1', PTP is enabled for TX on this port. */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_FLAGS_PTP_TX_TS_CAPTURE_ENABLE \
+ UINT32_C(0x20)
+ /*
+ * Priority setting for tunnel VLAN PRI to CoS mapping.
+ * # Each XXX_pri variable shall have a unique priority value
+ * when it is being used.
+ * # When comparing priorities of mappings, higher value
+ * indicates higher priority.
+ * For example, a value of 0-3 is returned where 0 is being
+ * the lowest priority and 3 is being the highest priority.
+ * # If the correspoding CoS mapping is not enabled, then this
+ * field should be ignored.
+ * # This value indicates the normalized priority value retained
+ * in the HWRM.
+ */
+ uint8_t tunnel_pri2cos_map_pri;
+ /*
+ * Priority setting for DSCP to PRI mapping.
+ * # Each XXX_pri variable shall have a unique priority value
+ * when it is being used.
+ * # When comparing priorities of mappings, higher value
+ * indicates higher priority.
+ * For example, a value of 0-3 is returned where 0 is being
+ * the lowest priority and 3 is being the highest priority.
+ * # If the correspoding CoS mapping is not enabled, then this
+ * field should be ignored.
+ * # This value indicates the normalized priority value retained
+ * in the HWRM.
+ */
+ uint8_t dscp2pri_map_pri;
+ /*
+ * This is a 16-bit bit mask that represents the
+ * current configuration of time stamp capture of PTP messages
+ * on the receive side of this port.
+ * If bit 'i' is set, then the receive side of the port
+ * is configured to capture the time stamp of every
+ * received PTP message with messageType field value set
+ * to i.
+ * If all bits are set to 0 (i.e. field value set 0),
+ * then the receive side of the port is not configured
+ * to capture timestamp for PTP messages.
+ * If all bits are set to 1, then the receive side of the
+ * port is configured to capture timestamp for all PTP
+ * messages.
+ */
+ uint16_t rx_ts_capture_ptp_msg_type;
+ /*
+ * This is a 16-bit bit mask that represents the
+ * current configuration of time stamp capture of PTP messages
+ * on the transmit side of this port.
+ * If bit 'i' is set, then the transmit side of the port
+ * is configured to capture the time stamp of every
+ * received PTP message with messageType field value set
+ * to i.
+ * If all bits are set to 0 (i.e. field value set 0),
+ * then the transmit side of the port is not configured
+ * to capture timestamp for PTP messages.
+ * If all bits are set to 1, then the transmit side of the
+ * port is configured to capture timestamp for all PTP
+ * messages.
+ */
+ uint16_t tx_ts_capture_ptp_msg_type;
+ /* Configuration of CoS fields. */
+ uint8_t cos_field_cfg;
+ /* Reserved */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_RSVD \
+ UINT32_C(0x1)
+ /*
+ * This field is used for selecting VLAN PRI value
+ * based on whether one or two VLAN Tags are present in
+ * the inner packet headers of tunneled packets or
+ * non-tunneled packets.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_VLAN_PRI_SEL_MASK \
+ UINT32_C(0x6)
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_VLAN_PRI_SEL_SFT \
+ 1
+ /*
+ * Select inner VLAN PRI when 1 or 2 VLAN Tags are
+ * present in the inner packet headers
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_VLAN_PRI_SEL_INNERMOST \
+ (UINT32_C(0x0) << 1)
+ /*
+ * Select outer VLAN Tag PRI when 2 VLAN Tags are
+ * present in the inner packet headers.
+ * No VLAN PRI is selected for this configuration
+ * if only one VLAN Tag is present in the inner
+ * packet headers.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_VLAN_PRI_SEL_OUTER \
+ (UINT32_C(0x1) << 1)
+ /*
+ * Select outermost VLAN PRI when 1 or 2 VLAN Tags
+ * are present in the inner packet headers
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_VLAN_PRI_SEL_OUTERMOST \
+ (UINT32_C(0x2) << 1)
+ /* Unspecified */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_VLAN_PRI_SEL_UNSPECIFIED \
+ (UINT32_C(0x3) << 1)
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_VLAN_PRI_SEL_LAST \
+ HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_VLAN_PRI_SEL_UNSPECIFIED
+ /*
+ * This field is used for selecting tunnel VLAN PRI value
+ * based on whether one or two VLAN Tags are present in
+ * the tunnel headers of tunneled packets. This selection
+ * does not apply to non-tunneled packets.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_MASK \
+ UINT32_C(0x18)
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_SFT \
+ 3
+ /*
+ * Select inner VLAN PRI when 1 or 2 VLAN Tags are
+ * present in the tunnel packet headers
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_INNERMOST \
+ (UINT32_C(0x0) << 3)
+ /*
+ * Select outer VLAN Tag PRI when 2 VLAN Tags are
+ * present in the tunnel packet headers.
+ * No VLAN PRI is selected for this configuration
+ * if only one VLAN Tag is present in the tunnel
+ * packet headers.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_OUTER \
+ (UINT32_C(0x1) << 3)
+ /*
+ * Select outermost VLAN PRI when 1 or 2 VLAN Tags
+ * are present in the tunnel packet headers
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_OUTERMOST \
+ (UINT32_C(0x2) << 3)
+ /* Unspecified */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_UNSPECIFIED \
+ (UINT32_C(0x3) << 3)
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_LAST \
+ HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_T_VLAN_PRI_SEL_UNSPECIFIED
+ /*
+ * This field is used to provide default CoS value that
+ * has been configured on this port.
+ */
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_DEFAULT_COS_MASK \
+ UINT32_C(0xe0)
+ #define HWRM_PORT_MAC_QCFG_OUTPUT_COS_FIELD_CFG_DEFAULT_COS_SFT \
+ 5
+ /*
+ * 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_port_mac_ptp_qcfg *
+ **************************/
+
+
+/* hwrm_port_mac_ptp_qcfg_input (size:192b/24B) */
+struct hwrm_port_mac_ptp_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Port ID of port that is being queried. */
+ uint16_t port_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_port_mac_ptp_qcfg_output (size:640b/80B) */
+struct hwrm_port_mac_ptp_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * In this field, a number of PTP related flags
+ * are used to indicate configured PTP capabilities.
+ */
+ uint8_t flags;
+ /*
+ * When this bit is set to '1', the PTP related registers are
+ * directly accessible by the host.
+ */
+ #define HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_DIRECT_ACCESS \
+ UINT32_C(0x1)
+ /*
+ * When this bit is set to '1', the PTP information is accessible
+ * via HWRM commands.
+ */
+ #define HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_HWRM_ACCESS \
+ UINT32_C(0x2)
+ uint8_t unused_0[3];
+ /* Offset of the PTP register for the lower 32 bits of timestamp for RX. */
+ uint32_t rx_ts_reg_off_lower;
+ /* Offset of the PTP register for the upper 32 bits of timestamp for RX. */
+ uint32_t rx_ts_reg_off_upper;
+ /* Offset of the PTP register for the sequence ID for RX. */
+ uint32_t rx_ts_reg_off_seq_id;
+ /* Offset of the first PTP source ID for RX. */
+ uint32_t rx_ts_reg_off_src_id_0;
+ /* Offset of the second PTP source ID for RX. */
+ uint32_t rx_ts_reg_off_src_id_1;
+ /* Offset of the third PTP source ID for RX. */
+ uint32_t rx_ts_reg_off_src_id_2;
+ /* Offset of the domain ID for RX. */
+ uint32_t rx_ts_reg_off_domain_id;
+ /* Offset of the PTP FIFO register for RX. */
+ uint32_t rx_ts_reg_off_fifo;
+ /* Offset of the PTP advance FIFO register for RX. */
+ uint32_t rx_ts_reg_off_fifo_adv;
+ /* PTP timestamp granularity for RX. */
+ uint32_t rx_ts_reg_off_granularity;
+ /* Offset of the PTP register for the lower 32 bits of timestamp for TX. */
+ uint32_t tx_ts_reg_off_lower;
+ /* Offset of the PTP register for the upper 32 bits of timestamp for TX. */
+ uint32_t tx_ts_reg_off_upper;
+ /* Offset of the PTP register for the sequence ID for TX. */
+ uint32_t tx_ts_reg_off_seq_id;
+ /* Offset of the PTP FIFO register for TX. */
+ uint32_t tx_ts_reg_off_fifo;
+ /* PTP timestamp granularity for TX. */
+ uint32_t tx_ts_reg_off_granularity;
+ uint8_t unused_1[7];
+ /*
+ * 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_port_qstats *
+ ********************/
+
+
+/* hwrm_port_qstats_input (size:320b/40B) */
+struct hwrm_port_qstats_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Port ID of port that is being queried. */
+ uint16_t port_id;
+ uint8_t unused_0[6];
+ /*
+ * This is the host address where
+ * Tx port statistics will be stored
+ */
+ uint64_t tx_stat_host_addr;
+ /*
+ * This is the host address where
+ * Rx port statistics will be stored
+ */
+ uint64_t rx_stat_host_addr;
+} __attribute__((packed));
+
+/* hwrm_port_qstats_output (size:128b/16B) */
+struct hwrm_port_qstats_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* The size of TX port statistics block in bytes. */
+ uint16_t tx_stat_size;
+ /* The size of RX port statistics block in bytes. */
+ uint16_t rx_stat_size;
+ uint8_t unused_0[3];
+ /*
+ * 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_port_qstats_ext *
+ ************************/
+
+
+/* hwrm_port_qstats_ext_input (size:320b/40B) */
+struct hwrm_port_qstats_ext_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Port ID of port that is being queried. */
+ uint16_t port_id;
+ /*
+ * The size of TX port extended
+ * statistics block in bytes.
+ */
+ uint16_t tx_stat_size;
+ /*
+ * The size of RX port extended
+ * statistics block in bytes
+ */
+ uint16_t rx_stat_size;
+ uint8_t unused_0[2];
+ /*
+ * This is the host address where
+ * Tx port statistics will be stored
+ */
+ uint64_t tx_stat_host_addr;
+ /*
+ * This is the host address where
+ * Rx port statistics will be stored
+ */
+ uint64_t rx_stat_host_addr;
+} __attribute__((packed));
+
+/* hwrm_port_qstats_ext_output (size:128b/16B) */
+struct hwrm_port_qstats_ext_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* The size of TX port statistics block in bytes. */
+ uint16_t tx_stat_size;
+ /* The size of RX port statistics block in bytes. */
+ uint16_t rx_stat_size;
+ uint8_t unused_0[3];
+ /*
+ * 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_port_lpbk_qstats *
+ *************************/
+
+
+/* hwrm_port_lpbk_qstats_input (size:128b/16B) */
+struct hwrm_port_lpbk_qstats_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+/* hwrm_port_lpbk_qstats_output (size:768b/96B) */
+struct hwrm_port_lpbk_qstats_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Number of transmitted unicast frames */
+ uint64_t lpbk_ucast_frames;
+ /* Number of transmitted multicast frames */
+ uint64_t lpbk_mcast_frames;
+ /* Number of transmitted broadcast frames */
+ uint64_t lpbk_bcast_frames;
+ /* Number of transmitted bytes for unicast traffic */
+ uint64_t lpbk_ucast_bytes;
+ /* Number of transmitted bytes for multicast traffic */
+ uint64_t lpbk_mcast_bytes;
+ /* Number of transmitted bytes for broadcast traffic */
+ uint64_t lpbk_bcast_bytes;
+ /* Total Tx Drops for loopback traffic reported by STATS block */
+ uint64_t tx_stat_discard;
+ /* Total Tx Error Drops for loopback traffic reported by STATS block */
+ uint64_t tx_stat_error;
+ /* Total Rx Drops for loopback traffic reported by STATS block */
+ uint64_t rx_stat_discard;
+ /* Total Rx Error Drops for loopback traffic reported by STATS block */
+ uint64_t rx_stat_error;
+ uint8_t unused_0[7];
+ /*
+ * 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_port_clr_stats *
+ ***********************/
+
+
+/* hwrm_port_clr_stats_input (size:192b/24B) */
+struct hwrm_port_clr_stats_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Port ID of port that is being queried. */
+ uint16_t port_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_port_clr_stats_output (size:128b/16B) */
+struct hwrm_port_clr_stats_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_port_lpbk_clr_stats *
+ ****************************/
+
+
+/* hwrm_port_lpbk_clr_stats_input (size:128b/16B) */
+struct hwrm_port_lpbk_clr_stats_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+/* hwrm_port_lpbk_clr_stats_output (size:128b/16B) */
+struct hwrm_port_lpbk_clr_stats_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_port_ts_query *
+ **********************/
+
+
+/* hwrm_port_ts_query_input (size:192b/24B) */
+struct hwrm_port_ts_query_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * 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_PORT_TS_QUERY_INPUT_FLAGS_PATH UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_TX UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_RX UINT32_C(0x1)
+ #define HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_LAST \
+ HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_RX
+ /* Port ID of port that is being queried. */
+ uint16_t port_id;
+ uint8_t unused_0[2];
+} __attribute__((packed));
+
+/* hwrm_port_ts_query_output (size:192b/24B) */
+struct hwrm_port_ts_query_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Timestamp value of PTP message captured. */
+ uint64_t ptp_msg_ts;
+ /* Sequence ID of the PTP message captured. */
+ uint16_t ptp_msg_seqid;
+ uint8_t unused_0[5];
+ /*
+ * 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_port_phy_qcaps *
+ ***********************/
+
+
+/* hwrm_port_phy_qcaps_input (size:192b/24B) */
+struct hwrm_port_phy_qcaps_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Port ID of port that is being queried. */
+ uint16_t port_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_port_phy_qcaps_output (size:192b/24B) */
+struct hwrm_port_phy_qcaps_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* PHY capability flags */
+ uint8_t flags;
+ /*
+ * If set to 1, then this field indicates that the
+ * link is capable of supporting EEE.
+ */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_EEE_SUPPORTED \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, then this field indicates that the
+ * PHY is capable of supporting external loopback.
+ */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_EXTERNAL_LPBK_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * Reserved field. The HWRM shall set this field to 0.
+ * An HWRM client shall ignore this field.
+ */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_RSVD1_MASK \
+ UINT32_C(0xfc)
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_RSVD1_SFT 2
+ /* Number of front panel ports for this device. */
+ uint8_t port_cnt;
+ /* Not supported or unknown */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_PORT_CNT_UNKNOWN UINT32_C(0x0)
+ /* single port device */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_PORT_CNT_1 UINT32_C(0x1)
+ /* 2-port device */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_PORT_CNT_2 UINT32_C(0x2)
+ /* 3-port device */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_PORT_CNT_3 UINT32_C(0x3)
+ /* 4-port device */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_PORT_CNT_4 UINT32_C(0x4)
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_PORT_CNT_LAST \
+ HWRM_PORT_PHY_QCAPS_OUTPUT_PORT_CNT_4
+ /*
+ * This is a bit mask to indicate what speeds are supported
+ * as forced speeds on this link.
+ * For each speed that can be forced on this link, the
+ * corresponding mask bit shall be set to '1'.
+ */
+ uint16_t supported_speeds_force_mode;
+ /* 100Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_100MBHD \
+ UINT32_C(0x1)
+ /* 100Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_100MB \
+ UINT32_C(0x2)
+ /* 1Gb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_1GBHD \
+ UINT32_C(0x4)
+ /* 1Gb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_1GB \
+ UINT32_C(0x8)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_2GB \
+ UINT32_C(0x10)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_2_5GB \
+ UINT32_C(0x20)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_10GB \
+ UINT32_C(0x40)
+ /* 20Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_20GB \
+ UINT32_C(0x80)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_25GB \
+ UINT32_C(0x100)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_40GB \
+ UINT32_C(0x200)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_50GB \
+ UINT32_C(0x400)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_100GB \
+ UINT32_C(0x800)
+ /* 10Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_10MBHD \
+ UINT32_C(0x1000)
+ /* 10Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_10MB \
+ UINT32_C(0x2000)
+ /*
+ * This is a bit mask to indicate what speeds are supported
+ * for autonegotiation on this link.
+ * For each speed that can be autonegotiated on this link, the
+ * corresponding mask bit shall be set to '1'.
+ */
+ uint16_t supported_speeds_auto_mode;
+ /* 100Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_100MBHD \
+ UINT32_C(0x1)
+ /* 100Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_100MB \
+ UINT32_C(0x2)
+ /* 1Gb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_1GBHD \
+ UINT32_C(0x4)
+ /* 1Gb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_1GB \
+ UINT32_C(0x8)
+ /* 2Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_2GB \
+ UINT32_C(0x10)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_2_5GB \
+ UINT32_C(0x20)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_10GB \
+ UINT32_C(0x40)
+ /* 20Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_20GB \
+ UINT32_C(0x80)
+ /* 25Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_25GB \
+ UINT32_C(0x100)
+ /* 40Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_40GB \
+ UINT32_C(0x200)
+ /* 50Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_50GB \
+ UINT32_C(0x400)
+ /* 100Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_100GB \
+ UINT32_C(0x800)
+ /* 10Mb link speed (Half-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_10MBHD \
+ UINT32_C(0x1000)
+ /* 10Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_10MB \
+ UINT32_C(0x2000)
+ /*
+ * This is a bit mask to indicate what speeds are supported
+ * for EEE on this link.
+ * For each speed that can be autonegotiated when EEE is enabled
+ * on this link, the corresponding mask bit shall be set to '1'.
+ * This field is only valid when the eee_suppotred is set to '1'.
+ */
+ uint16_t supported_speeds_eee_mode;
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_EEE_MODE_RSVD1 \
+ UINT32_C(0x1)
+ /* 100Mb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_EEE_MODE_100MB \
+ UINT32_C(0x2)
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_EEE_MODE_RSVD2 \
+ UINT32_C(0x4)
+ /* 1Gb link speed (Full-duplex) */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_EEE_MODE_1GB \
+ UINT32_C(0x8)
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_EEE_MODE_RSVD3 \
+ UINT32_C(0x10)
+ /* Reserved */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_EEE_MODE_RSVD4 \
+ UINT32_C(0x20)
+ /* 10Gb link speed */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_EEE_MODE_10GB \
+ UINT32_C(0x40)
+ uint32_t tx_lpi_timer_low;
+ /*
+ * The lowest value of TX LPI timer that can be set on this link
+ * when EEE is enabled. This value is in microseconds.
+ * This field is valid only when_eee_supported is set to '1'.
+ */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_TX_LPI_TIMER_LOW_MASK \
+ UINT32_C(0xffffff)
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_TX_LPI_TIMER_LOW_SFT 0
+ /*
+ * Reserved field. The HWRM shall set this field to 0.
+ * An HWRM client shall ignore this field.
+ */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_RSVD2_MASK \
+ UINT32_C(0xff000000)
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_RSVD2_SFT 24
+ uint32_t valid_tx_lpi_timer_high;
+ /*
+ * The highest value of TX LPI timer that can be set on this link
+ * when EEE is enabled. This value is in microseconds.
+ * This field is valid only when_eee_supported is set to '1'.
+ */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_TX_LPI_TIMER_HIGH_MASK \
+ UINT32_C(0xffffff)
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_TX_LPI_TIMER_HIGH_SFT 0
+ /*
+ * 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.
+ */
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_VALID_MASK \
+ UINT32_C(0xff000000)
+ #define HWRM_PORT_PHY_QCAPS_OUTPUT_VALID_SFT 24
+} __attribute__((packed));
+
+/***************************
+ * hwrm_port_phy_i2c_write *
+ ***************************/
+
+
+/* hwrm_port_phy_i2c_write_input (size:832b/104B) */
+struct hwrm_port_phy_i2c_write_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the page_offset field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_I2C_WRITE_INPUT_ENABLES_PAGE_OFFSET \
+ UINT32_C(0x1)
+ /* Port ID of port. */
+ uint16_t port_id;
+ /* 8-bit I2C slave address. */
+ uint8_t i2c_slave_addr;
+ uint8_t unused_0;
+ /* The page number that is being accessed over I2C. */
+ uint16_t page_number;
+ /* Offset within the page that is being accessed over I2C. */
+ uint16_t page_offset;
+ /*
+ * Length of data to write, in bytes starting at the offset
+ * specified above. If the offset is not specified, then
+ * the data shall be written from the beginning of the page.
+ */
+ uint8_t data_length;
+ uint8_t unused_1[7];
+ /* Up to 64B of data. */
+ uint32_t data[16];
+} __attribute__((packed));
+
+/* hwrm_port_phy_i2c_write_output (size:128b/16B) */
+struct hwrm_port_phy_i2c_write_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_port_phy_i2c_read *
+ **************************/
+
+
+/* hwrm_port_phy_i2c_read_input (size:320b/40B) */
+struct hwrm_port_phy_i2c_read_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the page_offset field to be
+ * configured.
+ */
+ #define HWRM_PORT_PHY_I2C_READ_INPUT_ENABLES_PAGE_OFFSET \
+ UINT32_C(0x1)
+ /* Port ID of port. */
+ uint16_t port_id;
+ /* 8-bit I2C slave address. */
+ uint8_t i2c_slave_addr;
+ uint8_t unused_0;
+ /* The page number that is being accessed over I2C. */
+ uint16_t page_number;
+ /* Offset within the page that is being accessed over I2C. */
+ uint16_t page_offset;
+ /*
+ * Length of data to read, in bytes starting at the offset
+ * specified above. If the offset is not specified, then
+ * the data shall be read from the beginning of the page.
+ */
+ uint8_t data_length;
+ uint8_t unused_1[7];
+} __attribute__((packed));
+
+/* hwrm_port_phy_i2c_read_output (size:640b/80B) */
+struct hwrm_port_phy_i2c_read_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Up to 64B of data. */
+ uint32_t data[16];
+ uint8_t unused_0[7];
+ /*
+ * 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_port_led_cfg *
+ *********************/
+
+
+/* hwrm_port_led_cfg_input (size:512b/64B) */
+struct hwrm_port_led_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the led0_id field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_ID \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the led0_state field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_STATE \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the led0_color field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_COLOR \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the led0_blink_on field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_ON \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the led0_blink_off field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_OFF \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the led0_group_id field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_GROUP_ID \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the led1_id field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_ID \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the led1_state field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_STATE \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the led1_color field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_COLOR \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the led1_blink_on field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_BLINK_ON \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the led1_blink_off field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_BLINK_OFF \
+ UINT32_C(0x400)
+ /*
+ * This bit must be '1' for the led1_group_id field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_GROUP_ID \
+ UINT32_C(0x800)
+ /*
+ * This bit must be '1' for the led2_id field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_ID \
+ UINT32_C(0x1000)
+ /*
+ * This bit must be '1' for the led2_state field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_STATE \
+ UINT32_C(0x2000)
+ /*
+ * This bit must be '1' for the led2_color field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_COLOR \
+ UINT32_C(0x4000)
+ /*
+ * This bit must be '1' for the led2_blink_on field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_BLINK_ON \
+ UINT32_C(0x8000)
+ /*
+ * This bit must be '1' for the led2_blink_off field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_BLINK_OFF \
+ UINT32_C(0x10000)
+ /*
+ * This bit must be '1' for the led2_group_id field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_GROUP_ID \
+ UINT32_C(0x20000)
+ /*
+ * This bit must be '1' for the led3_id field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_ID \
+ UINT32_C(0x40000)
+ /*
+ * This bit must be '1' for the led3_state field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_STATE \
+ UINT32_C(0x80000)
+ /*
+ * This bit must be '1' for the led3_color field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_COLOR \
+ UINT32_C(0x100000)
+ /*
+ * This bit must be '1' for the led3_blink_on field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_BLINK_ON \
+ UINT32_C(0x200000)
+ /*
+ * This bit must be '1' for the led3_blink_off field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_BLINK_OFF \
+ UINT32_C(0x400000)
+ /*
+ * This bit must be '1' for the led3_group_id field to be
+ * configured.
+ */
+ #define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_GROUP_ID \
+ UINT32_C(0x800000)
+ /* Port ID of port whose LEDs are configured. */
+ uint16_t port_id;
+ /*
+ * The number of LEDs that are being configured.
+ * Up to 4 LEDs can be configured with this command.
+ */
+ uint8_t num_leds;
+ /* Reserved field. */
+ uint8_t rsvd;
+ /* An identifier for the LED #0. */
+ uint8_t led0_id;
+ /* The requested state of the LED #0. */
+ uint8_t led0_state;
+ /* Default state of the LED */
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_DEFAULT UINT32_C(0x0)
+ /* Off */
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_OFF UINT32_C(0x1)
+ /* On */
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_ON UINT32_C(0x2)
+ /* Blink */
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINK UINT32_C(0x3)
+ /* Blink Alternately */
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINKALT UINT32_C(0x4)
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_LAST \
+ HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINKALT
+ /* The requested color of LED #0. */
+ uint8_t led0_color;
+ /* Default */
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_DEFAULT UINT32_C(0x0)
+ /* Amber */
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_AMBER UINT32_C(0x1)
+ /* Green */
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_GREEN UINT32_C(0x2)
+ /* Green or Amber */
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_GREENAMBER UINT32_C(0x3)
+ #define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_LAST \
+ HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_GREENAMBER
+ uint8_t unused_0;
+ /*
+ * If the LED #0 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED on between cycles.
+ */
+ uint16_t led0_blink_on;
+ /*
+ * If the LED #0 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED off between cycles.
+ */
+ uint16_t led0_blink_off;
+ /*
+ * An identifier for the group of LEDs that LED #0 belongs
+ * to.
+ * If set to 0, then the LED #0 shall not be grouped and
+ * shall be treated as an individual resource.
+ * For all other non-zero values of this field, LED #0 shall
+ * be grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led0_group_id;
+ /* Reserved field. */
+ uint8_t rsvd0;
+ /* An identifier for the LED #1. */
+ uint8_t led1_id;
+ /* The requested state of the LED #1. */
+ uint8_t led1_state;
+ /* Default state of the LED */
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_DEFAULT UINT32_C(0x0)
+ /* Off */
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_OFF UINT32_C(0x1)
+ /* On */
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_ON UINT32_C(0x2)
+ /* Blink */
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_BLINK UINT32_C(0x3)
+ /* Blink Alternately */
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_BLINKALT UINT32_C(0x4)
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_LAST \
+ HWRM_PORT_LED_CFG_INPUT_LED1_STATE_BLINKALT
+ /* The requested color of LED #1. */
+ uint8_t led1_color;
+ /* Default */
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_DEFAULT UINT32_C(0x0)
+ /* Amber */
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_AMBER UINT32_C(0x1)
+ /* Green */
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_GREEN UINT32_C(0x2)
+ /* Green or Amber */
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_GREENAMBER UINT32_C(0x3)
+ #define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_LAST \
+ HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_GREENAMBER
+ uint8_t unused_1;
+ /*
+ * If the LED #1 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED on between cycles.
+ */
+ uint16_t led1_blink_on;
+ /*
+ * If the LED #1 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED off between cycles.
+ */
+ uint16_t led1_blink_off;
+ /*
+ * An identifier for the group of LEDs that LED #1 belongs
+ * to.
+ * If set to 0, then the LED #1 shall not be grouped and
+ * shall be treated as an individual resource.
+ * For all other non-zero values of this field, LED #1 shall
+ * be grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led1_group_id;
+ /* Reserved field. */
+ uint8_t rsvd1;
+ /* An identifier for the LED #2. */
+ uint8_t led2_id;
+ /* The requested state of the LED #2. */
+ uint8_t led2_state;
+ /* Default state of the LED */
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_DEFAULT UINT32_C(0x0)
+ /* Off */
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_OFF UINT32_C(0x1)
+ /* On */
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_ON UINT32_C(0x2)
+ /* Blink */
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_BLINK UINT32_C(0x3)
+ /* Blink Alternately */
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_BLINKALT UINT32_C(0x4)
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_LAST \
+ HWRM_PORT_LED_CFG_INPUT_LED2_STATE_BLINKALT
+ /* The requested color of LED #2. */
+ uint8_t led2_color;
+ /* Default */
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_DEFAULT UINT32_C(0x0)
+ /* Amber */
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_AMBER UINT32_C(0x1)
+ /* Green */
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_GREEN UINT32_C(0x2)
+ /* Green or Amber */
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_GREENAMBER UINT32_C(0x3)
+ #define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_LAST \
+ HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_GREENAMBER
+ uint8_t unused_2;
+ /*
+ * If the LED #2 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED on between cycles.
+ */
+ uint16_t led2_blink_on;
+ /*
+ * If the LED #2 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED off between cycles.
+ */
+ uint16_t led2_blink_off;
+ /*
+ * An identifier for the group of LEDs that LED #2 belongs
+ * to.
+ * If set to 0, then the LED #2 shall not be grouped and
+ * shall be treated as an individual resource.
+ * For all other non-zero values of this field, LED #2 shall
+ * be grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led2_group_id;
+ /* Reserved field. */
+ uint8_t rsvd2;
+ /* An identifier for the LED #3. */
+ uint8_t led3_id;
+ /* The requested state of the LED #3. */
+ uint8_t led3_state;
+ /* Default state of the LED */
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_DEFAULT UINT32_C(0x0)
+ /* Off */
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_OFF UINT32_C(0x1)
+ /* On */
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_ON UINT32_C(0x2)
+ /* Blink */
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_BLINK UINT32_C(0x3)
+ /* Blink Alternately */
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_BLINKALT UINT32_C(0x4)
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_LAST \
+ HWRM_PORT_LED_CFG_INPUT_LED3_STATE_BLINKALT
+ /* The requested color of LED #3. */
+ uint8_t led3_color;
+ /* Default */
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_DEFAULT UINT32_C(0x0)
+ /* Amber */
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_AMBER UINT32_C(0x1)
+ /* Green */
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_GREEN UINT32_C(0x2)
+ /* Green or Amber */
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_GREENAMBER UINT32_C(0x3)
+ #define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_LAST \
+ HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_GREENAMBER
+ uint8_t unused_3;
+ /*
+ * If the LED #3 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED on between cycles.
+ */
+ uint16_t led3_blink_on;
+ /*
+ * If the LED #3 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED off between cycles.
+ */
+ uint16_t led3_blink_off;
+ /*
+ * An identifier for the group of LEDs that LED #3 belongs
+ * to.
+ * If set to 0, then the LED #3 shall not be grouped and
+ * shall be treated as an individual resource.
+ * For all other non-zero values of this field, LED #3 shall
+ * be grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led3_group_id;
+ /* Reserved field. */
+ uint8_t rsvd3;
+} __attribute__((packed));
+
+/* hwrm_port_led_cfg_output (size:128b/16B) */
+struct hwrm_port_led_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_port_led_qcfg *
+ **********************/
+
+
+/* hwrm_port_led_qcfg_input (size:192b/24B) */
+struct hwrm_port_led_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Port ID of port whose LED configuration is being queried. */
+ uint16_t port_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_port_led_qcfg_output (size:448b/56B) */
+struct hwrm_port_led_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * The number of LEDs that are configured on this port.
+ * Up to 4 LEDs can be returned in the response.
+ */
+ uint8_t num_leds;
+ /* An identifier for the LED #0. */
+ uint8_t led0_id;
+ /* The type of LED #0. */
+ uint8_t led0_type;
+ /* Speed LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_SPEED UINT32_C(0x0)
+ /* Activity LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_ACTIVITY UINT32_C(0x1)
+ /* Invalid */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_INVALID UINT32_C(0xff)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_INVALID
+ /* The current state of the LED #0. */
+ uint8_t led0_state;
+ /* Default state of the LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_DEFAULT UINT32_C(0x0)
+ /* Off */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_OFF UINT32_C(0x1)
+ /* On */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_ON UINT32_C(0x2)
+ /* Blink */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINK UINT32_C(0x3)
+ /* Blink Alternately */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINKALT UINT32_C(0x4)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINKALT
+ /* The color of LED #0. */
+ uint8_t led0_color;
+ /* Default */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_DEFAULT UINT32_C(0x0)
+ /* Amber */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_AMBER UINT32_C(0x1)
+ /* Green */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_GREEN UINT32_C(0x2)
+ /* Green or Amber */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_GREENAMBER UINT32_C(0x3)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_GREENAMBER
+ uint8_t unused_0;
+ /*
+ * If the LED #0 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED on between cycles.
+ */
+ uint16_t led0_blink_on;
+ /*
+ * If the LED #0 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED off between cycles.
+ */
+ uint16_t led0_blink_off;
+ /*
+ * An identifier for the group of LEDs that LED #0 belongs
+ * to.
+ * If set to 0, then the LED #0 is not grouped.
+ * For all other non-zero values of this field, LED #0 is
+ * grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led0_group_id;
+ /* An identifier for the LED #1. */
+ uint8_t led1_id;
+ /* The type of LED #1. */
+ uint8_t led1_type;
+ /* Speed LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_SPEED UINT32_C(0x0)
+ /* Activity LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_ACTIVITY UINT32_C(0x1)
+ /* Invalid */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_INVALID UINT32_C(0xff)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_INVALID
+ /* The current state of the LED #1. */
+ uint8_t led1_state;
+ /* Default state of the LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_DEFAULT UINT32_C(0x0)
+ /* Off */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_OFF UINT32_C(0x1)
+ /* On */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_ON UINT32_C(0x2)
+ /* Blink */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_BLINK UINT32_C(0x3)
+ /* Blink Alternately */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_BLINKALT UINT32_C(0x4)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_BLINKALT
+ /* The color of LED #1. */
+ uint8_t led1_color;
+ /* Default */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_DEFAULT UINT32_C(0x0)
+ /* Amber */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_AMBER UINT32_C(0x1)
+ /* Green */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_GREEN UINT32_C(0x2)
+ /* Green or Amber */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_GREENAMBER UINT32_C(0x3)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_GREENAMBER
+ uint8_t unused_1;
+ /*
+ * If the LED #1 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED on between cycles.
+ */
+ uint16_t led1_blink_on;
+ /*
+ * If the LED #1 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED off between cycles.
+ */
+ uint16_t led1_blink_off;
+ /*
+ * An identifier for the group of LEDs that LED #1 belongs
+ * to.
+ * If set to 0, then the LED #1 is not grouped.
+ * For all other non-zero values of this field, LED #1 is
+ * grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led1_group_id;
+ /* An identifier for the LED #2. */
+ uint8_t led2_id;
+ /* The type of LED #2. */
+ uint8_t led2_type;
+ /* Speed LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_SPEED UINT32_C(0x0)
+ /* Activity LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_ACTIVITY UINT32_C(0x1)
+ /* Invalid */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_INVALID UINT32_C(0xff)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_INVALID
+ /* The current state of the LED #2. */
+ uint8_t led2_state;
+ /* Default state of the LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_DEFAULT UINT32_C(0x0)
+ /* Off */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_OFF UINT32_C(0x1)
+ /* On */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_ON UINT32_C(0x2)
+ /* Blink */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_BLINK UINT32_C(0x3)
+ /* Blink Alternately */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_BLINKALT UINT32_C(0x4)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_BLINKALT
+ /* The color of LED #2. */
+ uint8_t led2_color;
+ /* Default */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_DEFAULT UINT32_C(0x0)
+ /* Amber */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_AMBER UINT32_C(0x1)
+ /* Green */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_GREEN UINT32_C(0x2)
+ /* Green or Amber */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_GREENAMBER UINT32_C(0x3)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_GREENAMBER
+ uint8_t unused_2;
+ /*
+ * If the LED #2 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED on between cycles.
+ */
+ uint16_t led2_blink_on;
+ /*
+ * If the LED #2 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED off between cycles.
+ */
+ uint16_t led2_blink_off;
+ /*
+ * An identifier for the group of LEDs that LED #2 belongs
+ * to.
+ * If set to 0, then the LED #2 is not grouped.
+ * For all other non-zero values of this field, LED #2 is
+ * grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led2_group_id;
+ /* An identifier for the LED #3. */
+ uint8_t led3_id;
+ /* The type of LED #3. */
+ uint8_t led3_type;
+ /* Speed LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_SPEED UINT32_C(0x0)
+ /* Activity LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_ACTIVITY UINT32_C(0x1)
+ /* Invalid */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_INVALID UINT32_C(0xff)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_INVALID
+ /* The current state of the LED #3. */
+ uint8_t led3_state;
+ /* Default state of the LED */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_DEFAULT UINT32_C(0x0)
+ /* Off */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_OFF UINT32_C(0x1)
+ /* On */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_ON UINT32_C(0x2)
+ /* Blink */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_BLINK UINT32_C(0x3)
+ /* Blink Alternately */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_BLINKALT UINT32_C(0x4)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_BLINKALT
+ /* The color of LED #3. */
+ uint8_t led3_color;
+ /* Default */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_DEFAULT UINT32_C(0x0)
+ /* Amber */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_AMBER UINT32_C(0x1)
+ /* Green */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_GREEN UINT32_C(0x2)
+ /* Green or Amber */
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_GREENAMBER UINT32_C(0x3)
+ #define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_LAST \
+ HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_GREENAMBER
+ uint8_t unused_3;
+ /*
+ * If the LED #3 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED on between cycles.
+ */
+ uint16_t led3_blink_on;
+ /*
+ * If the LED #3 state is "blink" or "blinkalt", then
+ * this field represents the requested time in milliseconds
+ * to keep LED off between cycles.
+ */
+ uint16_t led3_blink_off;
+ /*
+ * An identifier for the group of LEDs that LED #3 belongs
+ * to.
+ * If set to 0, then the LED #3 is not grouped.
+ * For all other non-zero values of this field, LED #3 is
+ * grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led3_group_id;
+ uint8_t unused_4[6];
+ /*
+ * 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_port_led_qcaps *
+ ***********************/
+
+
+/* hwrm_port_led_qcaps_input (size:192b/24B) */
+struct hwrm_port_led_qcaps_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Port ID of port whose LED configuration is being queried. */
+ uint16_t port_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_port_led_qcaps_output (size:384b/48B) */
+struct hwrm_port_led_qcaps_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * The number of LEDs that are configured on this port.
+ * Up to 4 LEDs can be returned in the response.
+ */
+ uint8_t num_leds;
+ /* Reserved for future use. */
+ uint8_t unused[3];
+ /* An identifier for the LED #0. */
+ uint8_t led0_id;
+ /* The type of LED #0. */
+ uint8_t led0_type;
+ /* Speed LED */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_SPEED UINT32_C(0x0)
+ /* Activity LED */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_ACTIVITY UINT32_C(0x1)
+ /* Invalid */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_INVALID UINT32_C(0xff)
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_LAST \
+ HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_INVALID
+ /*
+ * An identifier for the group of LEDs that LED #0 belongs
+ * to.
+ * If set to 0, then the LED #0 cannot be grouped.
+ * For all other non-zero values of this field, LED #0 is
+ * grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led0_group_id;
+ uint8_t unused_0;
+ /* The states supported by LED #0. */
+ uint16_t led0_state_caps;
+ /*
+ * If set to 1, this LED is enabled.
+ * If set to 0, this LED is disabled.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_ENABLED \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, off state is supported on this LED.
+ * If set to 0, off state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_OFF_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, on state is supported on this LED.
+ * If set to 0, on state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_ON_SUPPORTED \
+ UINT32_C(0x4)
+ /*
+ * If set to 1, blink state is supported on this LED.
+ * If set to 0, blink state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_BLINK_SUPPORTED \
+ UINT32_C(0x8)
+ /*
+ * If set to 1, blink_alt state is supported on this LED.
+ * If set to 0, blink_alt state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_BLINK_ALT_SUPPORTED \
+ UINT32_C(0x10)
+ /* The colors supported by LED #0. */
+ uint16_t led0_color_caps;
+ /* reserved. */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_RSVD \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, Amber color is supported on this LED.
+ * If set to 0, Amber color is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_AMBER_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, Green color is supported on this LED.
+ * If set to 0, Green color is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_GREEN_SUPPORTED \
+ UINT32_C(0x4)
+ /* An identifier for the LED #1. */
+ uint8_t led1_id;
+ /* The type of LED #1. */
+ uint8_t led1_type;
+ /* Speed LED */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_SPEED UINT32_C(0x0)
+ /* Activity LED */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_ACTIVITY UINT32_C(0x1)
+ /* Invalid */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_INVALID UINT32_C(0xff)
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_LAST \
+ HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_INVALID
+ /*
+ * An identifier for the group of LEDs that LED #1 belongs
+ * to.
+ * If set to 0, then the LED #0 cannot be grouped.
+ * For all other non-zero values of this field, LED #0 is
+ * grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led1_group_id;
+ uint8_t unused_1;
+ /* The states supported by LED #1. */
+ uint16_t led1_state_caps;
+ /*
+ * If set to 1, this LED is enabled.
+ * If set to 0, this LED is disabled.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_ENABLED \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, off state is supported on this LED.
+ * If set to 0, off state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_OFF_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, on state is supported on this LED.
+ * If set to 0, on state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_ON_SUPPORTED \
+ UINT32_C(0x4)
+ /*
+ * If set to 1, blink state is supported on this LED.
+ * If set to 0, blink state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_BLINK_SUPPORTED \
+ UINT32_C(0x8)
+ /*
+ * If set to 1, blink_alt state is supported on this LED.
+ * If set to 0, blink_alt state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_BLINK_ALT_SUPPORTED \
+ UINT32_C(0x10)
+ /* The colors supported by LED #1. */
+ uint16_t led1_color_caps;
+ /* reserved. */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_RSVD \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, Amber color is supported on this LED.
+ * If set to 0, Amber color is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_AMBER_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, Green color is supported on this LED.
+ * If set to 0, Green color is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_GREEN_SUPPORTED \
+ UINT32_C(0x4)
+ /* An identifier for the LED #2. */
+ uint8_t led2_id;
+ /* The type of LED #2. */
+ uint8_t led2_type;
+ /* Speed LED */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_SPEED UINT32_C(0x0)
+ /* Activity LED */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_ACTIVITY UINT32_C(0x1)
+ /* Invalid */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_INVALID UINT32_C(0xff)
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_LAST \
+ HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_INVALID
+ /*
+ * An identifier for the group of LEDs that LED #0 belongs
+ * to.
+ * If set to 0, then the LED #0 cannot be grouped.
+ * For all other non-zero values of this field, LED #0 is
+ * grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led2_group_id;
+ uint8_t unused_2;
+ /* The states supported by LED #2. */
+ uint16_t led2_state_caps;
+ /*
+ * If set to 1, this LED is enabled.
+ * If set to 0, this LED is disabled.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_ENABLED \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, off state is supported on this LED.
+ * If set to 0, off state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_OFF_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, on state is supported on this LED.
+ * If set to 0, on state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_ON_SUPPORTED \
+ UINT32_C(0x4)
+ /*
+ * If set to 1, blink state is supported on this LED.
+ * If set to 0, blink state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_BLINK_SUPPORTED \
+ UINT32_C(0x8)
+ /*
+ * If set to 1, blink_alt state is supported on this LED.
+ * If set to 0, blink_alt state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_BLINK_ALT_SUPPORTED \
+ UINT32_C(0x10)
+ /* The colors supported by LED #2. */
+ uint16_t led2_color_caps;
+ /* reserved. */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_RSVD \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, Amber color is supported on this LED.
+ * If set to 0, Amber color is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_AMBER_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, Green color is supported on this LED.
+ * If set to 0, Green color is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_GREEN_SUPPORTED \
+ UINT32_C(0x4)
+ /* An identifier for the LED #3. */
+ uint8_t led3_id;
+ /* The type of LED #3. */
+ uint8_t led3_type;
+ /* Speed LED */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_SPEED UINT32_C(0x0)
+ /* Activity LED */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_ACTIVITY UINT32_C(0x1)
+ /* Invalid */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_INVALID UINT32_C(0xff)
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_LAST \
+ HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_INVALID
+ /*
+ * An identifier for the group of LEDs that LED #3 belongs
+ * to.
+ * If set to 0, then the LED #0 cannot be grouped.
+ * For all other non-zero values of this field, LED #0 is
+ * grouped together with the LEDs with the same group ID
+ * value.
+ */
+ uint8_t led3_group_id;
+ uint8_t unused_3;
+ /* The states supported by LED #3. */
+ uint16_t led3_state_caps;
+ /*
+ * If set to 1, this LED is enabled.
+ * If set to 0, this LED is disabled.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_ENABLED \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, off state is supported on this LED.
+ * If set to 0, off state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_OFF_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, on state is supported on this LED.
+ * If set to 0, on state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_ON_SUPPORTED \
+ UINT32_C(0x4)
+ /*
+ * If set to 1, blink state is supported on this LED.
+ * If set to 0, blink state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_BLINK_SUPPORTED \
+ UINT32_C(0x8)
+ /*
+ * If set to 1, blink_alt state is supported on this LED.
+ * If set to 0, blink_alt state is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_BLINK_ALT_SUPPORTED \
+ UINT32_C(0x10)
+ /* The colors supported by LED #3. */
+ uint16_t led3_color_caps;
+ /* reserved. */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_RSVD \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, Amber color is supported on this LED.
+ * If set to 0, Amber color is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_AMBER_SUPPORTED \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, Green color is supported on this LED.
+ * If set to 0, Green color is not supported on this LED.
+ */
+ #define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_GREEN_SUPPORTED \
+ UINT32_C(0x4)
+ uint8_t unused_4[3];
+ /*
+ * 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 *
+ ***********************/
+
+
+/* hwrm_queue_qportcfg_input (size:192b/24B) */
+struct hwrm_queue_qportcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * 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)
+ /* rx path */
+ #define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX UINT32_C(0x1)
+ #define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST \
+ HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX
+ /*
+ * 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;
+ /*
+ * Drivers will set this capability when it can use
+ * queue_idx_service_profile to map the queues to application.
+ */
+ uint8_t drv_qmap_cap;
+ /* disabled */
+ #define HWRM_QUEUE_QPORTCFG_INPUT_DRV_QMAP_CAP_DISABLED UINT32_C(0x0)
+ /* enabled */
+ #define HWRM_QUEUE_QPORTCFG_INPUT_DRV_QMAP_CAP_ENABLED UINT32_C(0x1)
+ #define HWRM_QUEUE_QPORTCFG_INPUT_DRV_QMAP_CAP_LAST \
+ HWRM_QUEUE_QPORTCFG_INPUT_DRV_QMAP_CAP_ENABLED
+ uint8_t unused_0;
+} __attribute__((packed));
+
+/* hwrm_queue_qportcfg_output (size:256b/32B) */
+struct hwrm_queue_qportcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * The maximum number of queues that can be configured on this
+ * port.
+ * Valid values range from 1 through 8.
+ */
+ uint8_t max_configurable_queues;
+ /*
+ * The maximum number of lossless queues that can be configured
+ * on this port.
+ * Valid values range from 0 through 8.
+ */
+ uint8_t max_configurable_lossless_queues;
+ /*
+ * Bitmask indicating which queues can be configured by the
+ * hwrm_queue_cfg command.
+ *
+ * Each bit represents a specific queue where bit 0 represents
+ * queue 0 and bit 7 represents queue 7.
+ * # A value of 0 indicates that the queue is not configurable
+ * by the hwrm_queue_cfg command.
+ * # A value of 1 indicates that the queue is configurable.
+ * # A hwrm_queue_cfg command shall return error when trying to
+ * configure a queue not configurable.
+ */
+ uint8_t queue_cfg_allowed;
+ /* Information about queue configuration. */
+ uint8_t queue_cfg_info;
+ /*
+ * If this flag is set to '1', then the queues are
+ * configured asymmetrically on TX and RX sides.
+ * If this flag is set to '0', then the queues are
+ * configured symmetrically on TX and RX sides. For
+ * symmetric configuration, the queue configuration
+ * including queue ids and service profiles on the
+ * TX side is the same as the corresponding queue
+ * configuration on the RX side.
+ */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG \
+ UINT32_C(0x1)
+ /*
+ * Bitmask indicating which queues can be configured by the
+ * hwrm_queue_pfcenable_cfg command.
+ *
+ * Each bit represents a specific priority where bit 0 represents
+ * priority 0 and bit 7 represents priority 7.
+ * # A value of 0 indicates that the priority is not configurable by
+ * the hwrm_queue_pfcenable_cfg command.
+ * # A value of 1 indicates that the priority is configurable.
+ * # A hwrm_queue_pfcenable_cfg command shall return error when
+ * trying to configure a priority that is not configurable.
+ */
+ uint8_t queue_pfcenable_cfg_allowed;
+ /*
+ * Bitmask indicating which queues can be configured by the
+ * hwrm_queue_pri2cos_cfg command.
+ *
+ * Each bit represents a specific queue where bit 0 represents
+ * queue 0 and bit 7 represents queue 7.
+ * # A value of 0 indicates that the queue is not configurable
+ * by the hwrm_queue_pri2cos_cfg command.
+ * # A value of 1 indicates that the queue is configurable.
+ * # A hwrm_queue_pri2cos_cfg command shall return error when
+ * trying to configure a queue that is not configurable.
+ */
+ uint8_t queue_pri2cos_cfg_allowed;
+ /*
+ * Bitmask indicating which queues can be configured by the
+ * hwrm_queue_pri2cos_cfg command.
+ *
+ * Each bit represents a specific queue where bit 0 represents
+ * queue 0 and bit 7 represents queue 7.
+ * # A value of 0 indicates that the queue is not configurable
+ * by the hwrm_queue_pri2cos_cfg command.
+ * # A value of 1 indicates that the queue is configurable.
+ * # A hwrm_queue_pri2cos_cfg command shall return error when
+ * trying to configure a queue not configurable.
+ */
+ uint8_t queue_cos2bw_cfg_allowed;
+ /*
+ * ID of CoS Queue 0.
+ * FF - Invalid id
+ *
+ * # This ID can be used on any subsequent call to an hwrm command
+ * that takes a queue id.
+ * # IDs must always be queried by this command before any use
+ * by the driver or software.
+ * # Any driver or software should not make any assumptions about
+ * queue IDs.
+ * # A value of 0xff indicates that the queue is not available.
+ * # Available queues may not be in sequential order.
+ */
+ uint8_t queue_id0;
+ /* This value is applicable to CoS queues only. */
+ uint8_t queue_id0_service_profile;
+ /* Lossy (best-effort) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
+ UINT32_C(0x0)
+ /* Lossless (legacy) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
+ UINT32_C(0x1)
+ /* Lossless RoCE */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS_ROCE \
+ UINT32_C(0x1)
+ /* Lossy RoCE CNP */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY_ROCE_CNP \
+ UINT32_C(0x2)
+ /* Lossless NIC */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS_NIC \
+ UINT32_C(0x3)
+ /* 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)
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LAST \
+ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_UNKNOWN
+ /*
+ * ID of CoS Queue 1.
+ * FF - Invalid id
+ *
+ * # This ID can be used on any subsequent call to an hwrm command
+ * that takes a queue id.
+ * # IDs must always be queried by this command before any use
+ * by the driver or software.
+ * # Any driver or software should not make any assumptions about
+ * queue IDs.
+ * # A value of 0xff indicates that the queue is not available.
+ * # Available queues may not be in sequential order.
+ */
+ uint8_t queue_id1;
+ /* This value is applicable to CoS queues only. */
+ uint8_t queue_id1_service_profile;
+ /* Lossy (best-effort) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
+ UINT32_C(0x0)
+ /* Lossless (legacy) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
+ UINT32_C(0x1)
+ /* Lossless RoCE */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS_ROCE \
+ UINT32_C(0x1)
+ /* Lossy RoCE CNP */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY_ROCE_CNP \
+ UINT32_C(0x2)
+ /* Lossless NIC */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS_NIC \
+ UINT32_C(0x3)
+ /* 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)
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LAST \
+ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_UNKNOWN
+ /*
+ * ID of CoS Queue 2.
+ * FF - Invalid id
+ *
+ * # This ID can be used on any subsequent call to an hwrm command
+ * that takes a queue id.
+ * # IDs must always be queried by this command before any use
+ * by the driver or software.
+ * # Any driver or software should not make any assumptions about
+ * queue IDs.
+ * # A value of 0xff indicates that the queue is not available.
+ * # Available queues may not be in sequential order.
+ */
+ uint8_t queue_id2;
+ /* This value is applicable to CoS queues only. */
+ uint8_t queue_id2_service_profile;
+ /* Lossy (best-effort) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
+ UINT32_C(0x0)
+ /* Lossless (legacy) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
+ UINT32_C(0x1)
+ /* Lossless RoCE */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS_ROCE \
+ UINT32_C(0x1)
+ /* Lossy RoCE CNP */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY_ROCE_CNP \
+ UINT32_C(0x2)
+ /* Lossless NIC */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS_NIC \
+ UINT32_C(0x3)
+ /* 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)
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LAST \
+ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_UNKNOWN
+ /*
+ * ID of CoS Queue 3.
+ * FF - Invalid id
+ *
+ * # This ID can be used on any subsequent call to an hwrm command
+ * that takes a queue id.
+ * # IDs must always be queried by this command before any use
+ * by the driver or software.
+ * # Any driver or software should not make any assumptions about
+ * queue IDs.
+ * # A value of 0xff indicates that the queue is not available.
+ * # Available queues may not be in sequential order.
+ */
+ uint8_t queue_id3;
+ /* This value is applicable to CoS queues only. */
+ uint8_t queue_id3_service_profile;
+ /* Lossy (best-effort) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
+ UINT32_C(0x0)
+ /* Lossless (legacy) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
+ UINT32_C(0x1)
+ /* Lossless RoCE */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS_ROCE \
+ UINT32_C(0x1)
+ /* Lossy RoCE CNP */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY_ROCE_CNP \
+ UINT32_C(0x2)
+ /* Lossless NIC */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS_NIC \
+ UINT32_C(0x3)
+ /* 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)
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LAST \
+ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_UNKNOWN
+ /*
+ * ID of CoS Queue 4.
+ * FF - Invalid id
+ *
+ * # This ID can be used on any subsequent call to an hwrm command
+ * that takes a queue id.
+ * # IDs must always be queried by this command before any use
+ * by the driver or software.
+ * # Any driver or software should not make any assumptions about
+ * queue IDs.
+ * # A value of 0xff indicates that the queue is not available.
+ * # Available queues may not be in sequential order.
+ */
+ uint8_t queue_id4;
+ /* This value is applicable to CoS queues only. */
+ uint8_t queue_id4_service_profile;
+ /* Lossy (best-effort) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
+ UINT32_C(0x0)
+ /* Lossless (legacy) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
+ UINT32_C(0x1)
+ /* Lossless RoCE */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS_ROCE \
+ UINT32_C(0x1)
+ /* Lossy RoCE CNP */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY_ROCE_CNP \
+ UINT32_C(0x2)
+ /* Lossless NIC */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS_NIC \
+ UINT32_C(0x3)
+ /* 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)
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LAST \
+ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_UNKNOWN
+ /*
+ * ID of CoS Queue 5.
+ * FF - Invalid id
+ *
+ * # This ID can be used on any subsequent call to an hwrm command
+ * that takes a queue id.
+ * # IDs must always be queried by this command before any use
+ * by the driver or software.
+ * # Any driver or software should not make any assumptions about
+ * queue IDs.
+ * # A value of 0xff indicates that the queue is not available.
+ * # Available queues may not be in sequential order.
+ */
+ uint8_t queue_id5;
+ /* This value is applicable to CoS queues only. */
+ uint8_t queue_id5_service_profile;
+ /* Lossy (best-effort) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
+ UINT32_C(0x0)
+ /* Lossless (legacy) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
+ UINT32_C(0x1)
+ /* Lossless RoCE */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS_ROCE \
+ UINT32_C(0x1)
+ /* Lossy RoCE CNP */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY_ROCE_CNP \
+ UINT32_C(0x2)
+ /* Lossless NIC */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS_NIC \
+ UINT32_C(0x3)
+ /* 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)
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LAST \
+ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN
+ /*
+ * ID of CoS Queue 6.
+ * FF - Invalid id
+ *
+ * # This ID can be used on any subsequent call to an hwrm command
+ * that takes a queue id.
+ * # IDs must always be queried by this command before any use
+ * by the driver or software.
+ * # Any driver or software should not make any assumptions about
+ * queue IDs.
+ * # A value of 0xff indicates that the queue is not available.
+ * # Available queues may not be in sequential order.
+ */
+ uint8_t queue_id6;
+ /* This value is applicable to CoS queues only. */
+ uint8_t queue_id6_service_profile;
+ /* Lossy (best-effort) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSY \
+ UINT32_C(0x0)
+ /* Lossless (legacy) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
+ UINT32_C(0x1)
+ /* Lossless RoCE */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS_ROCE \
+ UINT32_C(0x1)
+ /* Lossy RoCE CNP */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSY_ROCE_CNP \
+ UINT32_C(0x2)
+ /* Lossless NIC */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS_NIC \
+ UINT32_C(0x3)
+ /* 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)
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LAST \
+ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN
+ /*
+ * ID of CoS Queue 7.
+ * FF - Invalid id
+ *
+ * # This ID can be used on any subsequent call to an hwrm command
+ * that takes a queue id.
+ * # IDs must always be queried by this command before any use
+ * by the driver or software.
+ * # Any driver or software should not make any assumptions about
+ * queue IDs.
+ * # A value of 0xff indicates that the queue is not available.
+ * # Available queues may not be in sequential order.
+ */
+ uint8_t queue_id7;
+ /* This value is applicable to CoS queues only. */
+ uint8_t queue_id7_service_profile;
+ /* Lossy (best-effort) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
+ UINT32_C(0x0)
+ /* Lossless (legacy) */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
+ UINT32_C(0x1)
+ /* Lossless RoCE */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS_ROCE \
+ UINT32_C(0x1)
+ /* Lossy RoCE CNP */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY_ROCE_CNP \
+ UINT32_C(0x2)
+ /* Lossless NIC */
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS_NIC \
+ UINT32_C(0x3)
+ /* 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)
+ #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LAST \
+ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN
+ /*
+ * 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_qcfg *
+ *******************/
+
+
+/* hwrm_queue_qcfg_input (size:192b/24B) */
+struct hwrm_queue_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * 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_QCFG_INPUT_FLAGS_PATH UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_QUEUE_QCFG_INPUT_FLAGS_PATH_TX UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_QUEUE_QCFG_INPUT_FLAGS_PATH_RX UINT32_C(0x1)
+ #define HWRM_QUEUE_QCFG_INPUT_FLAGS_PATH_LAST \
+ HWRM_QUEUE_QCFG_INPUT_FLAGS_PATH_RX
+ /* Queue ID of the queue. */
+ uint32_t queue_id;
+} __attribute__((packed));
+
+/* hwrm_queue_qcfg_output (size:128b/16B) */
+struct hwrm_queue_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * This value is a the estimate packet length used in the
+ * TX arbiter.
+ */
+ uint32_t queue_len;
+ /* This value is applicable to CoS queues only. */
+ uint8_t service_profile;
+ /* Lossy (best-effort) */
+ #define HWRM_QUEUE_QCFG_OUTPUT_SERVICE_PROFILE_LOSSY UINT32_C(0x0)
+ /* Lossless */
+ #define HWRM_QUEUE_QCFG_OUTPUT_SERVICE_PROFILE_LOSSLESS UINT32_C(0x1)
+ /* Set to 0xFF... (All Fs) if there is no service profile specified */
+ #define HWRM_QUEUE_QCFG_OUTPUT_SERVICE_PROFILE_UNKNOWN UINT32_C(0xff)
+ #define HWRM_QUEUE_QCFG_OUTPUT_SERVICE_PROFILE_LAST \
+ HWRM_QUEUE_QCFG_OUTPUT_SERVICE_PROFILE_UNKNOWN
+ /* Information about queue configuration. */
+ uint8_t queue_cfg_info;
+ /*
+ * If this flag is set to '1', then the queue is
+ * configured asymmetrically on TX and RX sides.
+ * If this flag is set to '0', then this queue is
+ * configured symmetrically on TX and RX sides.
+ */
+ #define HWRM_QUEUE_QCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG \
+ UINT32_C(0x1)
+ uint8_t unused_0;
+ /*
+ * 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_cfg *
+ ******************/
+
+
+/* hwrm_queue_cfg_input (size:320b/40B) */
+struct hwrm_queue_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * Enumeration denoting the RX, TX, or both directions applicable to the resource.
+ * This enumeration is used for resources that are similar for both
+ * TX and RX paths of the chip.
+ */
+ #define HWRM_QUEUE_CFG_INPUT_FLAGS_PATH_MASK UINT32_C(0x3)
+ #define HWRM_QUEUE_CFG_INPUT_FLAGS_PATH_SFT 0
+ /* tx path */
+ #define HWRM_QUEUE_CFG_INPUT_FLAGS_PATH_TX UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_QUEUE_CFG_INPUT_FLAGS_PATH_RX UINT32_C(0x1)
+ /* Bi-directional (Symmetrically applicable to TX and RX paths) */
+ #define HWRM_QUEUE_CFG_INPUT_FLAGS_PATH_BIDIR UINT32_C(0x2)
+ #define HWRM_QUEUE_CFG_INPUT_FLAGS_PATH_LAST \
+ HWRM_QUEUE_CFG_INPUT_FLAGS_PATH_BIDIR
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the dflt_len field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_CFG_INPUT_ENABLES_DFLT_LEN UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the service_profile field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_CFG_INPUT_ENABLES_SERVICE_PROFILE UINT32_C(0x2)
+ /* Queue ID of queue that is to be configured by this function. */
+ uint32_t queue_id;
+ /*
+ * This value is a the estimate packet length used in the
+ * TX arbiter.
+ * Set to 0xFF... (All Fs) to not adjust this value.
+ */
+ uint32_t dflt_len;
+ /* This value is applicable to CoS queues only. */
+ uint8_t service_profile;
+ /* Lossy (best-effort) */
+ #define HWRM_QUEUE_CFG_INPUT_SERVICE_PROFILE_LOSSY UINT32_C(0x0)
+ /* Lossless */
+ #define HWRM_QUEUE_CFG_INPUT_SERVICE_PROFILE_LOSSLESS UINT32_C(0x1)
+ /* Set to 0xFF... (All Fs) if there is no service profile specified */
+ #define HWRM_QUEUE_CFG_INPUT_SERVICE_PROFILE_UNKNOWN UINT32_C(0xff)
+ #define HWRM_QUEUE_CFG_INPUT_SERVICE_PROFILE_LAST \
+ HWRM_QUEUE_CFG_INPUT_SERVICE_PROFILE_UNKNOWN
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/* hwrm_queue_cfg_output (size:128b/16B) */
+struct hwrm_queue_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_pfcenable_qcfg *
+ *****************************/
+
+
+/* hwrm_queue_pfcenable_qcfg_input (size:192b/24B) */
+struct hwrm_queue_pfcenable_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * Port ID of port for which the table is being configured.
+ * The HWRM needs to check whether this function is allowed
+ * to configure pri2cos mapping on this port.
+ */
+ uint16_t port_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_queue_pfcenable_qcfg_output (size:128b/16B) */
+struct hwrm_queue_pfcenable_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint32_t flags;
+ /* If set to 1, then PFC is enabled on PRI 0. */
+ #define HWRM_QUEUE_PFCENABLE_QCFG_OUTPUT_FLAGS_PRI0_PFC_ENABLED \
+ UINT32_C(0x1)
+ /* If set to 1, then PFC is enabled on PRI 1. */
+ #define HWRM_QUEUE_PFCENABLE_QCFG_OUTPUT_FLAGS_PRI1_PFC_ENABLED \
+ UINT32_C(0x2)
+ /* If set to 1, then PFC is enabled on PRI 2. */
+ #define HWRM_QUEUE_PFCENABLE_QCFG_OUTPUT_FLAGS_PRI2_PFC_ENABLED \
+ UINT32_C(0x4)
+ /* If set to 1, then PFC is enabled on PRI 3. */
+ #define HWRM_QUEUE_PFCENABLE_QCFG_OUTPUT_FLAGS_PRI3_PFC_ENABLED \
+ UINT32_C(0x8)
+ /* If set to 1, then PFC is enabled on PRI 4. */
+ #define HWRM_QUEUE_PFCENABLE_QCFG_OUTPUT_FLAGS_PRI4_PFC_ENABLED \
+ UINT32_C(0x10)
+ /* If set to 1, then PFC is enabled on PRI 5. */
+ #define HWRM_QUEUE_PFCENABLE_QCFG_OUTPUT_FLAGS_PRI5_PFC_ENABLED \
+ UINT32_C(0x20)
+ /* If set to 1, then PFC is enabled on PRI 6. */
+ #define HWRM_QUEUE_PFCENABLE_QCFG_OUTPUT_FLAGS_PRI6_PFC_ENABLED \
+ UINT32_C(0x40)
+ /* If set to 1, then PFC is enabled on PRI 7. */
+ #define HWRM_QUEUE_PFCENABLE_QCFG_OUTPUT_FLAGS_PRI7_PFC_ENABLED \
+ UINT32_C(0x80)
+ uint8_t unused_0[3];
+ /*
+ * 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_pfcenable_cfg *
+ ****************************/
+
+
+/* hwrm_queue_pfcenable_cfg_input (size:192b/24B) */
+struct hwrm_queue_pfcenable_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /* If set to 1, then PFC is requested to be enabled on PRI 0. */
+ #define HWRM_QUEUE_PFCENABLE_CFG_INPUT_FLAGS_PRI0_PFC_ENABLED \
+ UINT32_C(0x1)
+ /* If set to 1, then PFC is requested to be enabled on PRI 1. */
+ #define HWRM_QUEUE_PFCENABLE_CFG_INPUT_FLAGS_PRI1_PFC_ENABLED \
+ UINT32_C(0x2)
+ /* If set to 1, then PFC is requested to be enabled on PRI 2. */
+ #define HWRM_QUEUE_PFCENABLE_CFG_INPUT_FLAGS_PRI2_PFC_ENABLED \
+ UINT32_C(0x4)
+ /* If set to 1, then PFC is requested to be enabled on PRI 3. */
+ #define HWRM_QUEUE_PFCENABLE_CFG_INPUT_FLAGS_PRI3_PFC_ENABLED \
+ UINT32_C(0x8)
+ /* If set to 1, then PFC is requested to be enabled on PRI 4. */
+ #define HWRM_QUEUE_PFCENABLE_CFG_INPUT_FLAGS_PRI4_PFC_ENABLED \
+ UINT32_C(0x10)
+ /* If set to 1, then PFC is requested to be enabled on PRI 5. */
+ #define HWRM_QUEUE_PFCENABLE_CFG_INPUT_FLAGS_PRI5_PFC_ENABLED \
+ UINT32_C(0x20)
+ /* If set to 1, then PFC is requested to be enabled on PRI 6. */
+ #define HWRM_QUEUE_PFCENABLE_CFG_INPUT_FLAGS_PRI6_PFC_ENABLED \
+ UINT32_C(0x40)
+ /* If set to 1, then PFC is requested to be enabled on PRI 7. */
+ #define HWRM_QUEUE_PFCENABLE_CFG_INPUT_FLAGS_PRI7_PFC_ENABLED \
+ UINT32_C(0x80)
+ /*
+ * Port ID of port for which the table is being configured.
+ * The HWRM needs to check whether this function is allowed
+ * to configure pri2cos mapping on this port.
+ */
+ uint16_t port_id;
+ uint8_t unused_0[2];
+} __attribute__((packed));
+
+/* hwrm_queue_pfcenable_cfg_output (size:128b/16B) */
+struct hwrm_queue_pfcenable_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_pri2cos_qcfg *
+ ***************************/
+
+
+/* hwrm_queue_pri2cos_qcfg_input (size:192b/24B) */
+struct hwrm_queue_pri2cos_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * 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_PRI2COS_QCFG_INPUT_FLAGS_PATH UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_TX UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_RX UINT32_C(0x1)
+ #define HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_LAST \
+ HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_RX
+ /*
+ * When this bit is set to '0', the query is
+ * for VLAN PRI field in tunnel headers.
+ * When this bit is set to '1', the query is
+ * for VLAN PRI field in inner packet headers.
+ */
+ #define HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_IVLAN UINT32_C(0x2)
+ /*
+ * Port ID of port for which the table is being configured.
+ * The HWRM needs to check whether this function is allowed
+ * to configure pri2cos mapping on this port.
+ */
+ uint8_t port_id;
+ uint8_t unused_0[3];
+} __attribute__((packed));
+
+/* hwrm_queue_pri2cos_qcfg_output (size:192b/24B) */
+struct hwrm_queue_pri2cos_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * CoS Queue assigned to priority 0. This value can only
+ * be changed before traffic has started.
+ * A value of 0xff indicates that no CoS queue is assigned to the
+ * specified priority.
+ */
+ uint8_t pri0_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 1. This value can only
+ * be changed before traffic has started.
+ * A value of 0xff indicates that no CoS queue is assigned to the
+ * specified priority.
+ */
+ uint8_t pri1_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 2 This value can only
+ * be changed before traffic has started.
+ * A value of 0xff indicates that no CoS queue is assigned to the
+ * specified priority.
+ */
+ uint8_t pri2_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 3. This value can only
+ * be changed before traffic has started.
+ * A value of 0xff indicates that no CoS queue is assigned to the
+ * specified priority.
+ */
+ uint8_t pri3_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 4. This value can only
+ * be changed before traffic has started.
+ * A value of 0xff indicates that no CoS queue is assigned to the
+ * specified priority.
+ */
+ uint8_t pri4_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 5. This value can only
+ * be changed before traffic has started.
+ * A value of 0xff indicates that no CoS queue is assigned to the
+ * specified priority.
+ */
+ uint8_t pri5_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 6. This value can only
+ * be changed before traffic has started.
+ * A value of 0xff indicates that no CoS queue is assigned to the
+ * specified priority.
+ */
+ uint8_t pri6_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 7. This value can only
+ * be changed before traffic has started.
+ * A value of 0xff indicates that no CoS queue is assigned to the
+ * specified priority.
+ */
+ uint8_t pri7_cos_queue_id;
+ /* Information about queue configuration. */
+ uint8_t queue_cfg_info;
+ /*
+ * If this flag is set to '1', then the PRI to CoS
+ * configuration is asymmetric on TX and RX sides.
+ * If this flag is set to '0', then PRI to CoS configuration
+ * is symmetric on TX and RX sides.
+ */
+ #define HWRM_QUEUE_PRI2COS_QCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG \
+ UINT32_C(0x1)
+ uint8_t unused_0[6];
+ /*
+ * 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_pri2cos_cfg *
+ **************************/
+
+
+/* hwrm_queue_pri2cos_cfg_input (size:320b/40B) */
+struct hwrm_queue_pri2cos_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * Enumeration denoting the RX, TX, or both directions applicable to the resource.
+ * This enumeration is used for resources that are similar for both
+ * TX and RX paths of the chip.
+ */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_MASK UINT32_C(0x3)
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_SFT 0
+ /* tx path */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_TX UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_RX UINT32_C(0x1)
+ /* Bi-directional (Symmetrically applicable to TX and RX paths) */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_BIDIR UINT32_C(0x2)
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_LAST \
+ HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_BIDIR
+ /*
+ * When this bit is set to '0', the mapping is requested
+ * for VLAN PRI field in tunnel headers.
+ * When this bit is set to '1', the mapping is requested
+ * for VLAN PRI field in inner packet headers.
+ */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_IVLAN UINT32_C(0x4)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the pri0_cos_queue_id field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_ENABLES_PRI0_COS_QUEUE_ID \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the pri1_cos_queue_id field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_ENABLES_PRI1_COS_QUEUE_ID \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the pri2_cos_queue_id field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_ENABLES_PRI2_COS_QUEUE_ID \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the pri3_cos_queue_id field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_ENABLES_PRI3_COS_QUEUE_ID \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the pri4_cos_queue_id field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_ENABLES_PRI4_COS_QUEUE_ID \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the pri5_cos_queue_id field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_ENABLES_PRI5_COS_QUEUE_ID \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the pri6_cos_queue_id field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_ENABLES_PRI6_COS_QUEUE_ID \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the pri7_cos_queue_id field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_PRI2COS_CFG_INPUT_ENABLES_PRI7_COS_QUEUE_ID \
+ UINT32_C(0x80)
+ /*
+ * Port ID of port for which the table is being configured.
+ * The HWRM needs to check whether this function is allowed
+ * to configure pri2cos mapping on this port.
+ */
+ uint8_t port_id;
+ /*
+ * CoS Queue assigned to priority 0. This value can only
+ * be changed before traffic has started.
+ */
+ uint8_t pri0_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 1. This value can only
+ * be changed before traffic has started.
+ */
+ uint8_t pri1_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 2 This value can only
+ * be changed before traffic has started.
+ */
+ uint8_t pri2_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 3. This value can only
+ * be changed before traffic has started.
+ */
+ uint8_t pri3_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 4. This value can only
+ * be changed before traffic has started.
+ */
+ uint8_t pri4_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 5. This value can only
+ * be changed before traffic has started.
+ */
+ uint8_t pri5_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 6. This value can only
+ * be changed before traffic has started.
+ */
+ uint8_t pri6_cos_queue_id;
+ /*
+ * CoS Queue assigned to priority 7. This value can only
+ * be changed before traffic has started.
+ */
+ uint8_t pri7_cos_queue_id;
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/* hwrm_queue_pri2cos_cfg_output (size:128b/16B) */
+struct hwrm_queue_pri2cos_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cos2bw_qcfg *
+ **************************/
+
+
+/* hwrm_queue_cos2bw_qcfg_input (size:192b/24B) */
+struct hwrm_queue_cos2bw_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * Port ID of port for which the table is being configured.
+ * The HWRM needs to check whether this function is allowed
+ * to configure TC BW assignment on this port.
+ */
+ uint16_t port_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_queue_cos2bw_qcfg_output (size:896b/112B) */
+struct hwrm_queue_cos2bw_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* ID of CoS Queue 0. */
+ uint8_t queue_id0;
+ uint8_t unused_0;
+ uint16_t unused_1;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id0_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id0_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id0_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id0_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id0_bw_weight;
+ /* ID of CoS Queue 1. */
+ uint8_t queue_id1;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id1_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id1_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id1_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID1_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id1_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id1_bw_weight;
+ /* ID of CoS Queue 2. */
+ uint8_t queue_id2;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id2_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id2_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id2_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID2_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id2_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id2_bw_weight;
+ /* ID of CoS Queue 3. */
+ uint8_t queue_id3;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id3_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id3_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id3_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID3_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id3_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id3_bw_weight;
+ /* ID of CoS Queue 4. */
+ uint8_t queue_id4;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id4_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id4_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id4_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID4_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id4_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id4_bw_weight;
+ /* ID of CoS Queue 5. */
+ uint8_t queue_id5;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id5_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id5_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id5_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID5_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id5_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id5_bw_weight;
+ /* ID of CoS Queue 6. */
+ uint8_t queue_id6;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id6_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id6_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id6_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID6_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id6_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id6_bw_weight;
+ /* ID of CoS Queue 7. */
+ uint8_t queue_id7;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id7_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id7_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id7_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID7_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id7_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id7_bw_weight;
+ uint8_t unused_2[4];
+ /*
+ * 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_cos2bw_cfg *
+ *************************/
+
+
+/* hwrm_queue_cos2bw_cfg_input (size:1024b/128B) */
+struct hwrm_queue_cos2bw_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ uint32_t enables;
+ /*
+ * If this bit is set to 1, then all queue_id0 related
+ * parameters in this command are valid.
+ */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_ENABLES_COS_QUEUE_ID0_VALID \
+ UINT32_C(0x1)
+ /*
+ * If this bit is set to 1, then all queue_id1 related
+ * parameters in this command are valid.
+ */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_ENABLES_COS_QUEUE_ID1_VALID \
+ UINT32_C(0x2)
+ /*
+ * If this bit is set to 1, then all queue_id2 related
+ * parameters in this command are valid.
+ */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_ENABLES_COS_QUEUE_ID2_VALID \
+ UINT32_C(0x4)
+ /*
+ * If this bit is set to 1, then all queue_id3 related
+ * parameters in this command are valid.
+ */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_ENABLES_COS_QUEUE_ID3_VALID \
+ UINT32_C(0x8)
+ /*
+ * If this bit is set to 1, then all queue_id4 related
+ * parameters in this command are valid.
+ */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_ENABLES_COS_QUEUE_ID4_VALID \
+ UINT32_C(0x10)
+ /*
+ * If this bit is set to 1, then all queue_id5 related
+ * parameters in this command are valid.
+ */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_ENABLES_COS_QUEUE_ID5_VALID \
+ UINT32_C(0x20)
+ /*
+ * If this bit is set to 1, then all queue_id6 related
+ * parameters in this command are valid.
+ */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_ENABLES_COS_QUEUE_ID6_VALID \
+ UINT32_C(0x40)
+ /*
+ * If this bit is set to 1, then all queue_id7 related
+ * parameters in this command are valid.
+ */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_ENABLES_COS_QUEUE_ID7_VALID \
+ UINT32_C(0x80)
+ /*
+ * Port ID of port for which the table is being configured.
+ * The HWRM needs to check whether this function is allowed
+ * to configure TC BW assignment on this port.
+ */
+ uint16_t port_id;
+ /* ID of CoS Queue 0. */
+ uint8_t queue_id0;
+ uint8_t unused_0;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id0_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id0_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id0_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID0_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id0_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id0_bw_weight;
+ /* ID of CoS Queue 1. */
+ uint8_t queue_id1;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id1_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id1_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id1_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID1_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id1_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id1_bw_weight;
+ /* ID of CoS Queue 2. */
+ uint8_t queue_id2;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id2_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id2_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id2_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID2_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id2_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id2_bw_weight;
+ /* ID of CoS Queue 3. */
+ uint8_t queue_id3;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id3_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id3_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id3_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID3_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id3_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id3_bw_weight;
+ /* ID of CoS Queue 4. */
+ uint8_t queue_id4;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id4_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id4_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id4_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID4_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id4_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id4_bw_weight;
+ /* ID of CoS Queue 5. */
+ uint8_t queue_id5;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id5_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id5_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id5_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID5_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id5_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id5_bw_weight;
+ /* ID of CoS Queue 6. */
+ uint8_t queue_id6;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id6_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id6_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id6_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID6_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id6_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id6_bw_weight;
+ /* ID of CoS Queue 7. */
+ uint8_t queue_id7;
+ /*
+ * Minimum BW allocated to CoS Queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id7_min_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MIN_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * Maximum BW allocated to CoS queue.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this COS inside the device.
+ */
+ uint32_t queue_id7_max_bw;
+ /* The bandwidth value. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_SCALE_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_MAX_BW_BW_VALUE_UNIT_INVALID
+ /* Transmission Selection Algorithm (TSA) for CoS Queue. */
+ uint8_t queue_id7_tsa_assign;
+ /* Strict Priority */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_TSA_ASSIGN_SP \
+ UINT32_C(0x0)
+ /* Enhanced Transmission Selection */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_TSA_ASSIGN_ETS \
+ UINT32_C(0x1)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_TSA_ASSIGN_RESERVED_FIRST \
+ UINT32_C(0x2)
+ /* reserved. */
+ #define HWRM_QUEUE_COS2BW_CFG_INPUT_QUEUE_ID7_TSA_ASSIGN_RESERVED_LAST \
+ UINT32_C(0xff)
+ /*
+ * Priority level for strict priority. Valid only when the
+ * tsa_assign is 0 - Strict Priority (SP)
+ * 0..7 - Valid values.
+ * 8..255 - Reserved.
+ */
+ uint8_t queue_id7_pri_lvl;
+ /*
+ * Weight used to allocate remaining BW for this COS after
+ * servicing guaranteed bandwidths for all COS.
+ */
+ uint8_t queue_id7_bw_weight;
+ uint8_t unused_1[5];
+} __attribute__((packed));
+
+/* hwrm_queue_cos2bw_cfg_output (size:128b/16B) */
+struct hwrm_queue_cos2bw_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_dscp_qcaps *
+ *************************/
+
+
+/* hwrm_queue_dscp_qcaps_input (size:192b/24B) */
+struct hwrm_queue_dscp_qcaps_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * Port ID of port for which the table is being configured.
+ * The HWRM needs to check whether this function is allowed
+ * to configure pri2cos mapping on this port.
+ */
+ uint8_t port_id;
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/* hwrm_queue_dscp_qcaps_output (size:128b/16B) */
+struct hwrm_queue_dscp_qcaps_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* The number of bits provided by the hardware for the DSCP value. */
+ uint8_t num_dscp_bits;
+ uint8_t unused_0;
+ /* Max number of DSCP-MASK-PRI entries supported. */
+ uint16_t max_entries;
+ uint8_t unused_1[3];
+ /*
+ * 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_dscp2pri_qcfg *
+ ****************************/
+
+
+/* hwrm_queue_dscp2pri_qcfg_input (size:256b/32B) */
+struct hwrm_queue_dscp2pri_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This is the host address where the 24-bits DSCP-MASK-PRI
+ * tuple(s) will be copied to.
+ */
+ uint64_t dest_data_addr;
+ /*
+ * Port ID of port for which the table is being configured.
+ * The HWRM needs to check whether this function is allowed
+ * to configure pri2cos mapping on this port.
+ */
+ uint8_t port_id;
+ uint8_t unused_0;
+ /* Size of the buffer pointed to by dest_data_addr. */
+ uint16_t dest_data_buffer_size;
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_queue_dscp2pri_qcfg_output (size:128b/16B) */
+struct hwrm_queue_dscp2pri_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * A count of the number of DSCP-MASK-PRI tuple(s) pointed to
+ * by the dest_data_addr.
+ */
+ uint16_t entry_cnt;
+ /*
+ * This is the default PRI which un-initialized DSCP values are
+ * mapped to.
+ */
+ uint8_t default_pri;
+ uint8_t unused_0[4];
+ /*
+ * 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_dscp2pri_cfg *
+ ***************************/
+
+
+/* hwrm_queue_dscp2pri_cfg_input (size:320b/40B) */
+struct hwrm_queue_dscp2pri_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This is the host address where the 24-bits DSCP-MASK-PRI tuple
+ * will be copied from.
+ */
+ uint64_t src_data_addr;
+ uint32_t flags;
+ /* use_hw_default_pri is 1 b */
+ #define HWRM_QUEUE_DSCP2PRI_CFG_INPUT_FLAGS_USE_HW_DEFAULT_PRI \
+ UINT32_C(0x1)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the default_pri field to be
+ * configured.
+ */
+ #define HWRM_QUEUE_DSCP2PRI_CFG_INPUT_ENABLES_DEFAULT_PRI \
+ UINT32_C(0x1)
+ /*
+ * Port ID of port for which the table is being configured.
+ * The HWRM needs to check whether this function is allowed
+ * to configure pri2cos mapping on this port.
+ */
+ uint8_t port_id;
+ /*
+ * This is the default PRI which un-initialized DSCP values will be
+ * mapped to.
+ */
+ uint8_t default_pri;
+ /*
+ * A count of the number of DSCP-MASK-PRI tuple(s) in the data pointed
+ * to by src_data_addr.
+ */
+ uint16_t entry_cnt;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_queue_dscp2pri_cfg_output (size:128b/16B) */
+struct hwrm_queue_dscp2pri_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_vnic_alloc *
+ *******************/
+
+
+/* hwrm_vnic_alloc_input (size:192b/24B) */
+struct hwrm_vnic_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * When this bit is '1', this VNIC is requested to
+ * be the default VNIC for this function.
+ */
+ #define HWRM_VNIC_ALLOC_INPUT_FLAGS_DEFAULT UINT32_C(0x1)
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_vnic_alloc_output (size:128b/16B) */
+struct hwrm_vnic_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Logical vnic ID */
+ uint32_t vnic_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_vnic_free *
+ ******************/
+
+
+/* hwrm_vnic_free_input (size:192b/24B) */
+struct hwrm_vnic_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Logical vnic ID */
+ uint32_t vnic_id;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_vnic_free_output (size:128b/16B) */
+struct hwrm_vnic_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_vnic_cfg *
+ *****************/
+
+
+/* hwrm_vnic_cfg_input (size:320b/40B) */
+struct hwrm_vnic_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * When this bit is '1', the VNIC is requested to
+ * be the default VNIC for the function.
+ */
+ #define HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', the VNIC is being configured to
+ * strip VLAN in the RX path.
+ * If set to '0', then VLAN stripping is disabled on
+ * this VNIC.
+ */
+ #define HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE \
+ UINT32_C(0x2)
+ /*
+ * When this bit is '1', the VNIC is being configured to
+ * buffer receive packets in the hardware until the host
+ * posts new receive buffers.
+ * If set to '0', then bd_stall is being configured to be
+ * disabled on this VNIC.
+ */
+ #define HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', the VNIC is being configured to
+ * receive both RoCE and non-RoCE traffic.
+ * If set to '0', then this VNIC is not configured to be
+ * operating in dual VNIC mode.
+ */
+ #define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_DUAL_VNIC_MODE \
+ UINT32_C(0x8)
+ /*
+ * When this flag is set to '1', the VNIC is requested to
+ * be configured to receive only RoCE traffic.
+ * If this flag is set to '0', then this flag shall be
+ * ignored by the HWRM.
+ * If roce_dual_vnic_mode flag is set to '1'
+ * or roce_mirroring_capable_vnic_mode flag to 1,
+ * then the HWRM client shall not set this flag to '1'.
+ */
+ #define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_ONLY_VNIC_MODE \
+ UINT32_C(0x10)
+ /*
+ * When a VNIC uses one destination ring group for certain
+ * application (e.g. Receive Flow Steering) where
+ * exact match is used to direct packets to a VNIC with one
+ * destination ring group only, there is no need to configure
+ * RSS indirection table for that VNIC as only one destination
+ * ring group is used.
+ *
+ * This flag is used to enable a mode where
+ * RSS is enabled in the VNIC using a RSS context
+ * for computing RSS hash but the RSS indirection table is
+ * not configured using hwrm_vnic_rss_cfg.
+ *
+ * If this mode is enabled, then the driver should not program
+ * RSS indirection table for the RSS context that is used for
+ * computing RSS hash only.
+ */
+ #define HWRM_VNIC_CFG_INPUT_FLAGS_RSS_DFLT_CR_MODE \
+ UINT32_C(0x20)
+ /*
+ * When this bit is '1', the VNIC is being configured to
+ * receive both RoCE and non-RoCE traffic, but forward only the
+ * RoCE traffic further. Also, RoCE traffic can be mirrored to
+ * L2 driver.
+ */
+ #define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_MIRRORING_CAPABLE_VNIC_MODE \
+ UINT32_C(0x40)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the dflt_ring_grp field to be
+ * configured.
+ */
+ #define HWRM_VNIC_CFG_INPUT_ENABLES_DFLT_RING_GRP \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the rss_rule field to be
+ * configured.
+ */
+ #define HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the cos_rule field to be
+ * configured.
+ */
+ #define HWRM_VNIC_CFG_INPUT_ENABLES_COS_RULE \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the lb_rule field to be
+ * configured.
+ */
+ #define HWRM_VNIC_CFG_INPUT_ENABLES_LB_RULE \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the mru field to be
+ * configured.
+ */
+ #define HWRM_VNIC_CFG_INPUT_ENABLES_MRU \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the default_rx_ring_id field to be
+ * configured.
+ */
+ #define HWRM_VNIC_CFG_INPUT_ENABLES_DEFAULT_RX_RING_ID \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the default_cmpl_ring_id field to be
+ * configured.
+ */
+ #define HWRM_VNIC_CFG_INPUT_ENABLES_DEFAULT_CMPL_RING_ID \
+ UINT32_C(0x40)
+ /* Logical vnic ID */
+ uint16_t vnic_id;
+ /*
+ * Default Completion ring for the VNIC. This ring will
+ * be chosen if packet does not match any RSS rules and if
+ * there is no COS rule.
+ */
+ uint16_t dflt_ring_grp;
+ /*
+ * RSS ID for RSS rule/table structure. 0xFF... (All Fs) if
+ * there is no RSS rule.
+ */
+ uint16_t rss_rule;
+ /*
+ * RSS ID for COS rule/table structure. 0xFF... (All Fs) if
+ * there is no COS rule.
+ */
+ uint16_t cos_rule;
+ /*
+ * RSS ID for load balancing rule/table structure.
+ * 0xFF... (All Fs) if there is no LB rule.
+ */
+ uint16_t lb_rule;
+ /*
+ * The maximum receive unit of the vnic.
+ * Each vnic is associated with a function.
+ * The vnic mru value overwrites the mru setting of the
+ * associated function.
+ * The HWRM shall make sure that vnic mru does not exceed
+ * the mru of the port the function is associated with.
+ */
+ uint16_t mru;
+ /*
+ * Default Rx ring for the VNIC. This ring will
+ * be chosen if packet does not match any RSS rules.
+ * The aggregation ring associated with the Rx ring is
+ * implied based on the Rx ring specified when the
+ * aggregation ring was allocated.
+ */
+ uint16_t default_rx_ring_id;
+ /*
+ * Default completion ring for the VNIC. This ring will
+ * be chosen if packet does not match any RSS rules.
+ */
+ uint16_t default_cmpl_ring_id;
+} __attribute__((packed));
+
+/* hwrm_vnic_cfg_output (size:128b/16B) */
+struct hwrm_vnic_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_vnic_qcfg *
+ ******************/
+
+
+/* hwrm_vnic_qcfg_input (size:256b/32B) */
+struct hwrm_vnic_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the vf_id_valid field to be
+ * configured.
+ */
+ #define HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID UINT32_C(0x1)
+ /* Logical vnic ID */
+ uint32_t vnic_id;
+ /* ID of Virtual Function whose VNIC resource is being queried. */
+ uint16_t vf_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_vnic_qcfg_output (size:256b/32B) */
+struct hwrm_vnic_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Default Completion ring for the VNIC. */
+ uint16_t dflt_ring_grp;
+ /*
+ * RSS ID for RSS rule/table structure. 0xFF... (All Fs) if
+ * there is no RSS rule.
+ */
+ uint16_t rss_rule;
+ /*
+ * RSS ID for COS rule/table structure. 0xFF... (All Fs) if
+ * there is no COS rule.
+ */
+ uint16_t cos_rule;
+ /*
+ * RSS ID for load balancing rule/table structure.
+ * 0xFF... (All Fs) if there is no LB rule.
+ */
+ uint16_t lb_rule;
+ /* The maximum receive unit of the vnic. */
+ uint16_t mru;
+ uint8_t unused_0[2];
+ uint32_t flags;
+ /*
+ * When this bit is '1', the VNIC is the default VNIC for
+ * the function.
+ */
+ #define HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * strip VLAN in the RX path.
+ * If set to '0', then VLAN stripping is disabled on
+ * this VNIC.
+ */
+ #define HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE \
+ UINT32_C(0x2)
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * buffer receive packets in the hardware until the host
+ * posts new receive buffers.
+ * If set to '0', then bd_stall is disabled on
+ * this VNIC.
+ */
+ #define HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * receive both RoCE and non-RoCE traffic.
+ * If set to '0', then this VNIC is not configured to
+ * operate in dual VNIC mode.
+ */
+ #define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE \
+ UINT32_C(0x8)
+ /*
+ * When this flag is set to '1', the VNIC is configured to
+ * receive only RoCE traffic.
+ * When this flag is set to '0', the VNIC is not configured
+ * to receive only RoCE traffic.
+ * If roce_dual_vnic_mode flag and this flag both are set
+ * to '1', then it is an invalid configuration of the
+ * VNIC. The HWRM should not allow that type of
+ * mis-configuration by HWRM clients.
+ */
+ #define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE \
+ UINT32_C(0x10)
+ /*
+ * When a VNIC uses one destination ring group for certain
+ * application (e.g. Receive Flow Steering) where
+ * exact match is used to direct packets to a VNIC with one
+ * destination ring group only, there is no need to configure
+ * RSS indirection table for that VNIC as only one destination
+ * ring group is used.
+ *
+ * When this bit is set to '1', then the VNIC is enabled in a
+ * mode where RSS is enabled in the VNIC using a RSS context
+ * for computing RSS hash but the RSS indirection table is
+ * not configured.
+ */
+ #define HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE \
+ UINT32_C(0x20)
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * receive both RoCE and non-RoCE traffic, but forward only
+ * RoCE traffic further. Also RoCE traffic can be mirrored to
+ * L2 driver.
+ */
+ #define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_MIRRORING_CAPABLE_VNIC_MODE \
+ UINT32_C(0x40)
+ uint8_t unused_1[7];
+ /*
+ * 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_vnic_qcaps *
+ *******************/
+
+
+/* hwrm_vnic_qcaps_input (size:192b/24B) */
+struct hwrm_vnic_qcaps_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_vnic_qcaps_output (size:192b/24B) */
+struct hwrm_vnic_qcaps_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* The maximum receive unit that is settable on a vnic. */
+ uint16_t mru;
+ uint8_t unused_0[2];
+ uint32_t flags;
+ /* Unused. */
+ #define HWRM_VNIC_QCAPS_OUTPUT_FLAGS_UNUSED \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', the capability of stripping VLAN in
+ * the RX path is supported on VNIC(s).
+ * If set to '0', then VLAN stripping capability is
+ * not supported on VNIC(s).
+ */
+ #define HWRM_VNIC_QCAPS_OUTPUT_FLAGS_VLAN_STRIP_CAP \
+ UINT32_C(0x2)
+ /*
+ * When this bit is '1', the capability to buffer receive
+ * packets in the hardware until the host posts new receive buffers
+ * is supported on VNIC(s).
+ * If set to '0', then bd_stall capability is not supported
+ * on VNIC(s).
+ */
+ #define HWRM_VNIC_QCAPS_OUTPUT_FLAGS_BD_STALL_CAP \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', the capability to
+ * receive both RoCE and non-RoCE traffic on VNIC(s) is
+ * supported.
+ * If set to '0', then the capability to receive
+ * both RoCE and non-RoCE traffic on VNIC(s) is
+ * not supported.
+ */
+ #define HWRM_VNIC_QCAPS_OUTPUT_FLAGS_ROCE_DUAL_VNIC_CAP \
+ UINT32_C(0x8)
+ /*
+ * When this bit is set to '1', the capability to configure
+ * a VNIC to receive only RoCE traffic is supported.
+ * When this flag is set to '0', the VNIC capability to
+ * configure to receive only RoCE traffic is not supported.
+ */
+ #define HWRM_VNIC_QCAPS_OUTPUT_FLAGS_ROCE_ONLY_VNIC_CAP \
+ UINT32_C(0x10)
+ /*
+ * When this bit is set to '1', then the capability to enable
+ * a VNIC in a mode where RSS context without configuring
+ * RSS indirection table is supported (for RSS hash computation).
+ * When this bit is set to '0', then a VNIC can not be configured
+ * with a mode to enable RSS context without configuring RSS
+ * indirection table.
+ */
+ #define HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RSS_DFLT_CR_CAP \
+ UINT32_C(0x20)
+ /*
+ * When this bit is '1', the capability to
+ * mirror the the RoCE traffic is supported.
+ * If set to '0', then the capability to mirror the
+ * RoCE traffic is not supported.
+ */
+ #define HWRM_VNIC_QCAPS_OUTPUT_FLAGS_ROCE_MIRRORING_CAPABLE_VNIC_CAP \
+ UINT32_C(0x40)
+ /*
+ * When this bit is '1', the outermost RSS hashing capability
+ * is supported. If set to '0', then the outermost RSS hashing
+ * capability is not supported.
+ */
+ #define HWRM_VNIC_QCAPS_OUTPUT_FLAGS_OUTERMOST_RSS_CAP \
+ UINT32_C(0x80)
+ uint8_t unused_1[7];
+ /*
+ * 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_vnic_tpa_cfg *
+ *********************/
+
+
+/* hwrm_vnic_tpa_cfg_input (size:320b/40B) */
+struct hwrm_vnic_tpa_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * When this bit is '1', the VNIC shall be configured to
+ * perform transparent packet aggregation (TPA) of
+ * non-tunneled TCP packets.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', the VNIC shall be configured to
+ * perform transparent packet aggregation (TPA) of
+ * tunneled TCP packets.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA \
+ UINT32_C(0x2)
+ /*
+ * When this bit is '1', the VNIC shall be configured to
+ * perform transparent packet aggregation (TPA) according
+ * to Windows Receive Segment Coalescing (RSC) rules.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', the VNIC shall be configured to
+ * perform transparent packet aggregation (TPA) according
+ * to Linux Generic Receive Offload (GRO) rules.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO \
+ UINT32_C(0x8)
+ /*
+ * When this bit is '1', the VNIC shall be configured to
+ * perform transparent packet aggregation (TPA) for TCP
+ * packets with IP ECN set to non-zero.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN \
+ UINT32_C(0x10)
+ /*
+ * When this bit is '1', the VNIC shall be configured to
+ * perform transparent packet aggregation (TPA) for
+ * GRE tunneled TCP packets only if all packets have the
+ * same GRE sequence.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ \
+ UINT32_C(0x20)
+ /*
+ * When this bit is '1' and the GRO mode is enabled,
+ * the VNIC shall be configured to
+ * perform transparent packet aggregation (TPA) for
+ * TCP/IPv4 packets with consecutively increasing IPIDs.
+ * In other words, the last packet that is being
+ * aggregated to an already existing aggregation context
+ * shall have IPID 1 more than the IPID of the last packet
+ * that was aggregated in that aggregation context.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO_IPID_CHECK \
+ UINT32_C(0x40)
+ /*
+ * When this bit is '1' and the GRO mode is enabled,
+ * the VNIC shall be configured to
+ * perform transparent packet aggregation (TPA) for
+ * TCP packets with the same TTL (IPv4) or Hop limit (IPv6)
+ * value.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO_TTL_CHECK \
+ UINT32_C(0x80)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the max_agg_segs field to be
+ * configured.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the max_aggs field to be
+ * configured.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the max_agg_timer field to be
+ * configured.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_TIMER UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the min_agg_len field to be
+ * configured.
+ */
+ #define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN UINT32_C(0x8)
+ /* Logical vnic ID */
+ uint16_t vnic_id;
+ /*
+ * This is the maximum number of TCP segments that can
+ * be aggregated (unit is Log2). Max value is 31.
+ */
+ uint16_t max_agg_segs;
+ /* 1 segment */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_1 UINT32_C(0x0)
+ /* 2 segments */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_2 UINT32_C(0x1)
+ /* 4 segments */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_4 UINT32_C(0x2)
+ /* 8 segments */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_8 UINT32_C(0x3)
+ /* Any segment size larger than this is not valid */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX UINT32_C(0x1f)
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_LAST \
+ HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX
+ /*
+ * This is the maximum number of aggregations this VNIC is
+ * allowed (unit is Log2). Max value is 7
+ */
+ uint16_t max_aggs;
+ /* 1 aggregation */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_1 UINT32_C(0x0)
+ /* 2 aggregations */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_2 UINT32_C(0x1)
+ /* 4 aggregations */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_4 UINT32_C(0x2)
+ /* 8 aggregations */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_8 UINT32_C(0x3)
+ /* 16 aggregations */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_16 UINT32_C(0x4)
+ /* Any aggregation size larger than this is not valid */
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX UINT32_C(0x7)
+ #define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_LAST \
+ HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX
+ uint8_t unused_0[2];
+ /*
+ * This is the maximum amount of time allowed for
+ * an aggregation context to complete after it was initiated.
+ */
+ uint32_t max_agg_timer;
+ /*
+ * This is the minimum amount of payload length required to
+ * start an aggregation context.
+ */
+ uint32_t min_agg_len;
+} __attribute__((packed));
+
+/* hwrm_vnic_tpa_cfg_output (size:128b/16B) */
+struct hwrm_vnic_tpa_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_vnic_tpa_qcfg *
+ **********************/
+
+
+/* hwrm_vnic_tpa_qcfg_input (size:192b/24B) */
+struct hwrm_vnic_tpa_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Logical vnic ID */
+ uint16_t vnic_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_vnic_tpa_qcfg_output (size:256b/32B) */
+struct hwrm_vnic_tpa_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint32_t flags;
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * perform transparent packet aggregation (TPA) of
+ * non-tunneled TCP packets.
+ */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_FLAGS_TPA \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * perform transparent packet aggregation (TPA) of
+ * tunneled TCP packets.
+ */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_FLAGS_ENCAP_TPA \
+ UINT32_C(0x2)
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * perform transparent packet aggregation (TPA) according
+ * to Windows Receive Segment Coalescing (RSC) rules.
+ */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_FLAGS_RSC_WND_UPDATE \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * perform transparent packet aggregation (TPA) according
+ * to Linux Generic Receive Offload (GRO) rules.
+ */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_FLAGS_GRO \
+ UINT32_C(0x8)
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * perform transparent packet aggregation (TPA) for TCP
+ * packets with IP ECN set to non-zero.
+ */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_FLAGS_AGG_WITH_ECN \
+ UINT32_C(0x10)
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * perform transparent packet aggregation (TPA) for
+ * GRE tunneled TCP packets only if all packets have the
+ * same GRE sequence.
+ */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ \
+ UINT32_C(0x20)
+ /*
+ * When this bit is '1' and the GRO mode is enabled,
+ * the VNIC is configured to
+ * perform transparent packet aggregation (TPA) for
+ * TCP/IPv4 packets with consecutively increasing IPIDs.
+ * In other words, the last packet that is being
+ * aggregated to an already existing aggregation context
+ * shall have IPID 1 more than the IPID of the last packet
+ * that was aggregated in that aggregation context.
+ */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_FLAGS_GRO_IPID_CHECK \
+ UINT32_C(0x40)
+ /*
+ * When this bit is '1' and the GRO mode is enabled,
+ * the VNIC is configured to
+ * perform transparent packet aggregation (TPA) for
+ * TCP packets with the same TTL (IPv4) or Hop limit (IPv6)
+ * value.
+ */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_FLAGS_GRO_TTL_CHECK \
+ UINT32_C(0x80)
+ /*
+ * This is the maximum number of TCP segments that can
+ * be aggregated (unit is Log2). Max value is 31.
+ */
+ uint16_t max_agg_segs;
+ /* 1 segment */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGG_SEGS_1 UINT32_C(0x0)
+ /* 2 segments */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGG_SEGS_2 UINT32_C(0x1)
+ /* 4 segments */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGG_SEGS_4 UINT32_C(0x2)
+ /* 8 segments */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGG_SEGS_8 UINT32_C(0x3)
+ /* Any segment size larger than this is not valid */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGG_SEGS_MAX UINT32_C(0x1f)
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGG_SEGS_LAST \
+ HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGG_SEGS_MAX
+ /*
+ * This is the maximum number of aggregations this VNIC is
+ * allowed (unit is Log2). Max value is 7
+ */
+ uint16_t max_aggs;
+ /* 1 aggregation */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGGS_1 UINT32_C(0x0)
+ /* 2 aggregations */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGGS_2 UINT32_C(0x1)
+ /* 4 aggregations */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGGS_4 UINT32_C(0x2)
+ /* 8 aggregations */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGGS_8 UINT32_C(0x3)
+ /* 16 aggregations */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGGS_16 UINT32_C(0x4)
+ /* Any aggregation size larger than this is not valid */
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGGS_MAX UINT32_C(0x7)
+ #define HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGGS_LAST \
+ HWRM_VNIC_TPA_QCFG_OUTPUT_MAX_AGGS_MAX
+ /*
+ * This is the maximum amount of time allowed for
+ * an aggregation context to complete after it was initiated.
+ */
+ uint32_t max_agg_timer;
+ /*
+ * This is the minimum amount of payload length required to
+ * start an aggregation context.
+ */
+ uint32_t min_agg_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_vnic_rss_cfg *
+ *********************/
+
+
+/* hwrm_vnic_rss_cfg_input (size:384b/48B) */
+struct hwrm_vnic_rss_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t hash_type;
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source and destination IPv4 addresses of IPv4
+ * packets.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 UINT32_C(0x1)
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source/destination IPv4 addresses and
+ * source/destination ports of TCP/IPv4 packets.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4 UINT32_C(0x2)
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source/destination IPv4 addresses and
+ * source/destination ports of UDP/IPv4 packets.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4 UINT32_C(0x4)
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source and destination IPv4 addresses of IPv6
+ * packets.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6 UINT32_C(0x8)
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source/destination IPv6 addresses and
+ * source/destination ports of TCP/IPv6 packets.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6 UINT32_C(0x10)
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source/destination IPv6 addresses and
+ * source/destination ports of UDP/IPv6 packets.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6 UINT32_C(0x20)
+ /* VNIC ID of VNIC associated with RSS table being configured. */
+ uint16_t vnic_id;
+ /*
+ * Specifies which VNIC ring table pair to configure.
+ * Valid values range from 0 to 7.
+ */
+ uint8_t ring_table_pair_index;
+ /* Flags to specify different RSS hash modes. */
+ uint8_t hash_mode_flags;
+ /*
+ * When this bit is '1', it indicates using current RSS
+ * hash mode setting configured in the device.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', it indicates requesting support of
+ * RSS hashing over innermost 4 tuples {l3.src, l3.dest,
+ * l4.src, l4.dest} for tunnel packets. For none-tunnel
+ * packets, the RSS hash is computed over the normal
+ * src/dest l3 and src/dest l4 headers.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_4 \
+ UINT32_C(0x2)
+ /*
+ * When this bit is '1', it indicates requesting support of
+ * RSS hashing over innermost 2 tuples {l3.src, l3.dest} for
+ * tunnel packets. For none-tunnel packets, the RSS hash is
+ * computed over the normal src/dest l3 headers.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_2 \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', it indicates requesting support of
+ * RSS hashing over outermost 4 tuples {t_l3.src, t_l3.dest,
+ * t_l4.src, t_l4.dest} for tunnel packets. For none-tunnel
+ * packets, the RSS hash is computed over the normal
+ * src/dest l3 and src/dest l4 headers.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_4 \
+ UINT32_C(0x8)
+ /*
+ * When this bit is '1', it indicates requesting support of
+ * RSS hashing over outermost 2 tuples {t_l3.src, t_l3.dest} for
+ * tunnel packets. For none-tunnel packets, the RSS hash is
+ * computed over the normal src/dest l3 headers.
+ */
+ #define HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_2 \
+ UINT32_C(0x10)
+ /* This is the address for rss ring group table */
+ uint64_t ring_grp_tbl_addr;
+ /* This is the address for rss hash key table */
+ uint64_t hash_key_tbl_addr;
+ /* Index to the rss indirection table. */
+ uint16_t rss_ctx_idx;
+ uint8_t unused_1[6];
+} __attribute__((packed));
+
+/* hwrm_vnic_rss_cfg_output (size:128b/16B) */
+struct hwrm_vnic_rss_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_vnic_rss_qcfg *
+ **********************/
+
+
+/* hwrm_vnic_rss_qcfg_input (size:192b/24B) */
+struct hwrm_vnic_rss_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Index to the rss indirection table. */
+ uint16_t rss_ctx_idx;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_vnic_rss_qcfg_output (size:512b/64B) */
+struct hwrm_vnic_rss_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint32_t hash_type;
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source and destination IPv4 addresses of IPv4
+ * packets.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_TYPE_IPV4 UINT32_C(0x1)
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source/destination IPv4 addresses and
+ * source/destination ports of TCP/IPv4 packets.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_TYPE_TCP_IPV4 UINT32_C(0x2)
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source/destination IPv4 addresses and
+ * source/destination ports of UDP/IPv4 packets.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_TYPE_UDP_IPV4 UINT32_C(0x4)
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source and destination IPv4 addresses of IPv6
+ * packets.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_TYPE_IPV6 UINT32_C(0x8)
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source/destination IPv6 addresses and
+ * source/destination ports of TCP/IPv6 packets.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_TYPE_TCP_IPV6 UINT32_C(0x10)
+ /*
+ * When this bit is '1', the RSS hash shall be computed
+ * over source/destination IPv6 addresses and
+ * source/destination ports of UDP/IPv6 packets.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_TYPE_UDP_IPV6 UINT32_C(0x20)
+ uint8_t unused_0[4];
+ /* This is the value of rss hash key */
+ uint32_t hash_key[10];
+ /* Flags to specify different RSS hash modes. */
+ uint8_t hash_mode_flags;
+ /*
+ * When this bit is '1', it indicates using current RSS
+ * hash mode setting configured in the device.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_MODE_FLAGS_DEFAULT \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', it indicates requesting support of
+ * RSS hashing over innermost 4 tuples {l3.src, l3.dest,
+ * l4.src, l4.dest} for tunnel packets. For none-tunnel
+ * packets, the RSS hash is computed over the normal
+ * src/dest l3 and src/dest l4 headers.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_MODE_FLAGS_INNERMOST_4 \
+ UINT32_C(0x2)
+ /*
+ * When this bit is '1', it indicates requesting support of
+ * RSS hashing over innermost 2 tuples {l3.src, l3.dest} for
+ * tunnel packets. For none-tunnel packets, the RSS hash is
+ * computed over the normal src/dest l3 headers.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_MODE_FLAGS_INNERMOST_2 \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', it indicates requesting support of
+ * RSS hashing over outermost 4 tuples {t_l3.src, t_l3.dest,
+ * t_l4.src, t_l4.dest} for tunnel packets. For none-tunnel
+ * packets, the RSS hash is computed over the normal
+ * src/dest l3 and src/dest l4 headers.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_MODE_FLAGS_OUTERMOST_4 \
+ UINT32_C(0x8)
+ /*
+ * When this bit is '1', it indicates requesting support of
+ * RSS hashing over outermost 2 tuples {t_l3.src, t_l3.dest} for
+ * tunnel packets. For none-tunnel packets, the RSS hash is
+ * computed over the normal src/dest l3 headers.
+ */
+ #define HWRM_VNIC_RSS_QCFG_OUTPUT_HASH_MODE_FLAGS_OUTERMOST_2 \
+ UINT32_C(0x10)
+ uint8_t unused_1[6];
+ /*
+ * 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_vnic_plcmodes_cfg *
+ **************************/
+
+
+/* hwrm_vnic_plcmodes_cfg_input (size:320b/40B) */
+struct hwrm_vnic_plcmodes_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * When this bit is '1', the VNIC shall be configured to
+ * use regular placement algorithm.
+ * By default, the regular placement algorithm shall be
+ * enabled on the VNIC.
+ */
+ #define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', the VNIC shall be configured
+ * use the jumbo placement algorithm.
+ */
+ #define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT \
+ UINT32_C(0x2)
+ /*
+ * When this bit is '1', the VNIC shall be configured
+ * to enable Header-Data split for IPv4 packets according
+ * to the following rules:
+ * # If the packet is identified as TCP/IPv4, then the
+ * packet is split at the beginning of the TCP payload.
+ * # If the packet is identified as UDP/IPv4, then the
+ * packet is split at the beginning of UDP payload.
+ * # If the packet is identified as non-TCP and non-UDP
+ * IPv4 packet, then the packet is split at the beginning
+ * of the upper layer protocol header carried in the IPv4
+ * packet.
+ */
+ #define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', the VNIC shall be configured
+ * to enable Header-Data split for IPv6 packets according
+ * to the following rules:
+ * # If the packet is identified as TCP/IPv6, then the
+ * packet is split at the beginning of the TCP payload.
+ * # If the packet is identified as UDP/IPv6, then the
+ * packet is split at the beginning of UDP payload.
+ * # If the packet is identified as non-TCP and non-UDP
+ * IPv6 packet, then the packet is split at the beginning
+ * of the upper layer protocol header carried in the IPv6
+ * packet.
+ */
+ #define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6 \
+ UINT32_C(0x8)
+ /*
+ * When this bit is '1', the VNIC shall be configured
+ * to enable Header-Data split for FCoE packets at the
+ * beginning of FC payload.
+ */
+ #define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_FCOE \
+ UINT32_C(0x10)
+ /*
+ * When this bit is '1', the VNIC shall be configured
+ * to enable Header-Data split for RoCE packets at the
+ * beginning of RoCE payload (after BTH/GRH headers).
+ */
+ #define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_ROCE \
+ UINT32_C(0x20)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the jumbo_thresh_valid field to be
+ * configured.
+ */
+ #define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the hds_offset_valid field to be
+ * configured.
+ */
+ #define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_OFFSET_VALID \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the hds_threshold_valid field to be
+ * configured.
+ */
+ #define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID \
+ UINT32_C(0x4)
+ /* Logical vnic ID */
+ uint32_t vnic_id;
+ /*
+ * When jumbo placement algorithm is enabled, this value
+ * is used to determine the threshold for jumbo placement.
+ * Packets with length larger than this value will be
+ * placed according to the jumbo placement algorithm.
+ */
+ uint16_t jumbo_thresh;
+ /*
+ * This value is used to determine the offset into
+ * packet buffer where the split data (payload) will be
+ * placed according to one of of HDS placement algorithm.
+ *
+ * The lengths of packet buffers provided for split data
+ * shall be larger than this value.
+ */
+ uint16_t hds_offset;
+ /*
+ * When one of the HDS placement algorithm is enabled, this
+ * value is used to determine the threshold for HDS
+ * placement.
+ * Packets with length larger than this value will be
+ * placed according to the HDS placement algorithm.
+ * This value shall be in multiple of 4 bytes.
+ */
+ uint16_t hds_threshold;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_vnic_plcmodes_cfg_output (size:128b/16B) */
+struct hwrm_vnic_plcmodes_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_vnic_plcmodes_qcfg *
+ ***************************/
+
+
+/* hwrm_vnic_plcmodes_qcfg_input (size:192b/24B) */
+struct hwrm_vnic_plcmodes_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Logical vnic ID */
+ uint32_t vnic_id;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_vnic_plcmodes_qcfg_output (size:192b/24B) */
+struct hwrm_vnic_plcmodes_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint32_t flags;
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * use regular placement algorithm.
+ */
+ #define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_REGULAR_PLACEMENT \
+ UINT32_C(0x1)
+ /*
+ * When this bit is '1', the VNIC is configured to
+ * use the jumbo placement algorithm.
+ */
+ #define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_JUMBO_PLACEMENT \
+ UINT32_C(0x2)
+ /*
+ * When this bit is '1', the VNIC is configured
+ * to enable Header-Data split for IPv4 packets.
+ */
+ #define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_IPV4 \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', the VNIC is configured
+ * to enable Header-Data split for IPv6 packets.
+ */
+ #define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_IPV6 \
+ UINT32_C(0x8)
+ /*
+ * When this bit is '1', the VNIC is configured
+ * to enable Header-Data split for FCoE packets.
+ */
+ #define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_FCOE \
+ UINT32_C(0x10)
+ /*
+ * When this bit is '1', the VNIC is configured
+ * to enable Header-Data split for RoCE packets.
+ */
+ #define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_ROCE \
+ UINT32_C(0x20)
+ /*
+ * When this bit is '1', the VNIC is configured
+ * to be the default VNIC of the requesting function.
+ */
+ #define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_DFLT_VNIC \
+ UINT32_C(0x40)
+ /*
+ * When jumbo placement algorithm is enabled, this value
+ * is used to determine the threshold for jumbo placement.
+ * Packets with length larger than this value will be
+ * placed according to the jumbo placement algorithm.
+ */
+ uint16_t jumbo_thresh;
+ /*
+ * This value is used to determine the offset into
+ * packet buffer where the split data (payload) will be
+ * placed according to one of of HDS placement algorithm.
+ *
+ * The lengths of packet buffers provided for split data
+ * shall be larger than this value.
+ */
+ uint16_t hds_offset;
+ /*
+ * When one of the HDS placement algorithm is enabled, this
+ * value is used to determine the threshold for HDS
+ * placement.
+ * Packets with length larger than this value will be
+ * placed according to the HDS placement algorithm.
+ * This value shall be in multiple of 4 bytes.
+ */
+ uint16_t hds_threshold;
+ uint8_t unused_0[5];
+ /*
+ * 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_vnic_rss_cos_lb_ctx_alloc *
+ **********************************/
+
+
+/* hwrm_vnic_rss_cos_lb_ctx_alloc_input (size:128b/16B) */
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+/* hwrm_vnic_rss_cos_lb_ctx_alloc_output (size:128b/16B) */
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* rss_cos_lb_ctx_id is 16 b */
+ uint16_t rss_cos_lb_ctx_id;
+ uint8_t unused_0[5];
+ /*
+ * 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_vnic_rss_cos_lb_ctx_free *
+ *********************************/
+
+
+/* hwrm_vnic_rss_cos_lb_ctx_free_input (size:192b/24B) */
+struct hwrm_vnic_rss_cos_lb_ctx_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* rss_cos_lb_ctx_id is 16 b */
+ uint16_t rss_cos_lb_ctx_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_vnic_rss_cos_lb_ctx_free_output (size:128b/16B) */
+struct hwrm_vnic_rss_cos_lb_ctx_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_ring_alloc *
+ *******************/
+
+
+/* hwrm_ring_alloc_input (size:640b/80B) */
+struct hwrm_ring_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the ring_arb_cfg field to be
+ * configured.
+ */
+ #define HWRM_RING_ALLOC_INPUT_ENABLES_RING_ARB_CFG \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the stat_ctx_id_valid field to be
+ * configured.
+ */
+ #define HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the max_bw_valid field to be
+ * configured.
+ */
+ #define HWRM_RING_ALLOC_INPUT_ENABLES_MAX_BW_VALID \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the rx_ring_id field to be
+ * configured.
+ */
+ #define HWRM_RING_ALLOC_INPUT_ENABLES_RX_RING_ID_VALID \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the nq_ring_id field to be
+ * configured.
+ */
+ #define HWRM_RING_ALLOC_INPUT_ENABLES_NQ_RING_ID_VALID \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the rx_buf_size field to be
+ * configured.
+ */
+ #define HWRM_RING_ALLOC_INPUT_ENABLES_RX_BUF_SIZE_VALID \
+ UINT32_C(0x100)
+ /* Ring Type. */
+ uint8_t ring_type;
+ /* L2 Completion Ring (CR) */
+ #define HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL UINT32_C(0x0)
+ /* TX Ring (TR) */
+ #define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX UINT32_C(0x1)
+ /* RX Ring (RR) */
+ #define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX UINT32_C(0x2)
+ /* RoCE Notification Completion Ring (ROCE_CR) */
+ #define HWRM_RING_ALLOC_INPUT_RING_TYPE_ROCE_CMPL UINT32_C(0x3)
+ /* RX Aggregation Ring */
+ #define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX_AGG UINT32_C(0x4)
+ /* Notification Queue */
+ #define HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ UINT32_C(0x5)
+ #define HWRM_RING_ALLOC_INPUT_RING_TYPE_LAST \
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ
+ uint8_t unused_0[3];
+ /*
+ * This value is a pointer to the page table for the
+ * Ring.
+ */
+ uint64_t page_tbl_addr;
+ /* First Byte Offset of the first entry in the first page. */
+ uint32_t fbo;
+ /*
+ * Actual page size in 2^page_size. The supported range is increments
+ * in powers of 2 from 16 bytes to 1GB.
+ * - 4 = 16 B
+ * Page size is 16 B.
+ * - 12 = 4 KB
+ * Page size is 4 KB.
+ * - 13 = 8 KB
+ * Page size is 8 KB.
+ * - 16 = 64 KB
+ * Page size is 64 KB.
+ * - 21 = 2 MB
+ * Page size is 2 MB.
+ * - 22 = 4 MB
+ * Page size is 4 MB.
+ * - 30 = 1 GB
+ * Page size is 1 GB.
+ */
+ uint8_t page_size;
+ /*
+ * This value indicates the depth of page table.
+ * For this version of the specification, value other than 0 or
+ * 1 shall be considered as an invalid value.
+ * When the page_tbl_depth = 0, then it is treated as a
+ * special case with the following.
+ * 1. FBO and page size fields are not valid.
+ * 2. page_tbl_addr is the physical address of the first
+ * element of the ring.
+ */
+ uint8_t page_tbl_depth;
+ uint8_t unused_1[2];
+ /*
+ * Number of 16B units in the ring. Minimum size for
+ * a ring is 16 16B entries.
+ */
+ uint32_t length;
+ /*
+ * Logical ring number for the ring to be allocated.
+ * This value determines the position in the doorbell
+ * area where the update to the ring will be made.
+ *
+ * For completion rings, this value is also the MSI-X
+ * vector number for the function the completion ring is
+ * associated with.
+ */
+ uint16_t logical_id;
+ /*
+ * This field is used only when ring_type is a TX ring.
+ * This value indicates what completion ring the TX ring
+ * is associated with.
+ */
+ uint16_t cmpl_ring_id;
+ /*
+ * This field is used only when ring_type is a TX ring.
+ * This value indicates what CoS queue the TX ring
+ * is associated with.
+ */
+ uint16_t queue_id;
+ /*
+ * When allocating a Rx ring or Rx aggregation ring, this field
+ * specifies the size of the buffer descriptors posted to the ring.
+ */
+ uint16_t rx_buf_size;
+ /*
+ * When allocating an Rx aggregation ring, this field
+ * specifies the associated Rx ring ID.
+ */
+ uint16_t rx_ring_id;
+ /*
+ * When allocating a completion ring, this field
+ * specifies the associated NQ ring ID.
+ */
+ uint16_t nq_ring_id;
+ /*
+ * This field is used only when ring_type is a TX ring.
+ * This field is used to configure arbitration related
+ * parameters for a TX ring.
+ */
+ uint16_t ring_arb_cfg;
+ /* Arbitration policy used for the ring. */
+ #define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_MASK \
+ UINT32_C(0xf)
+ #define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SFT 0
+ /*
+ * Use strict priority for the TX ring.
+ * Priority value is specified in arb_policy_param
+ */
+ #define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SP \
+ UINT32_C(0x1)
+ /*
+ * Use weighted fair queue arbitration for the TX ring.
+ * Weight is specified in arb_policy_param
+ */
+ #define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ \
+ UINT32_C(0x2)
+ #define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_LAST \
+ HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ
+ /* Reserved field. */
+ #define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_MASK \
+ UINT32_C(0xf0)
+ #define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_SFT 4
+ /*
+ * Arbitration policy specific parameter.
+ * # For strict priority arbitration policy, this field
+ * represents a priority value. If set to 0, then the priority
+ * is not specified and the HWRM is allowed to select
+ * any priority for this TX ring.
+ * # For weighted fair queue arbitration policy, this field
+ * represents a weight value. If set to 0, then the weight
+ * is not specified and the HWRM is allowed to select
+ * any weight for this TX ring.
+ */
+ #define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_MASK \
+ UINT32_C(0xff00)
+ #define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_SFT 8
+ uint16_t unused_3;
+ /*
+ * This field is reserved for the future use.
+ * It shall be set to 0.
+ */
+ uint32_t reserved3;
+ /*
+ * This field is used only when ring_type is a TX ring.
+ * This input indicates what statistics context this ring
+ * should be associated with.
+ */
+ uint32_t stat_ctx_id;
+ /*
+ * This field is reserved for the future use.
+ * It shall be set to 0.
+ */
+ uint32_t reserved4;
+ /*
+ * This field is used only when ring_type is a TX ring
+ * to specify maximum BW allocated to the TX ring.
+ * The HWRM will translate this value into byte counter and
+ * time interval used for this ring inside the device.
+ */
+ uint32_t max_bw;
+ /* The bandwidth value. */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_SFT 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_LAST \
+ HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_SFT 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
+ HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
+ /*
+ * This field is used only when ring_type is a Completion ring.
+ * This value indicates what interrupt mode should be used
+ * on this completion ring.
+ * Note: In the legacy interrupt mode, no more than 16
+ * completion rings are allowed.
+ */
+ uint8_t int_mode;
+ /* Legacy INTA */
+ #define HWRM_RING_ALLOC_INPUT_INT_MODE_LEGACY UINT32_C(0x0)
+ /* Reserved */
+ #define HWRM_RING_ALLOC_INPUT_INT_MODE_RSVD UINT32_C(0x1)
+ /* MSI-X */
+ #define HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX UINT32_C(0x2)
+ /* No Interrupt - Polled mode */
+ #define HWRM_RING_ALLOC_INPUT_INT_MODE_POLL UINT32_C(0x3)
+ #define HWRM_RING_ALLOC_INPUT_INT_MODE_LAST \
+ HWRM_RING_ALLOC_INPUT_INT_MODE_POLL
+ uint8_t unused_4[3];
+} __attribute__((packed));
+
+/* hwrm_ring_alloc_output (size:128b/16B) */
+struct hwrm_ring_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * Physical number of ring allocated.
+ * This value shall be unique for a ring type.
+ */
+ uint16_t ring_id;
+ /* Logical number of ring allocated. */
+ uint16_t logical_ring_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_ring_free *
+ ******************/
+
+
+/* hwrm_ring_free_input (size:192b/24B) */
+struct hwrm_ring_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Ring Type. */
+ uint8_t ring_type;
+ /* L2 Completion Ring (CR) */
+ #define HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL UINT32_C(0x0)
+ /* TX Ring (TR) */
+ #define HWRM_RING_FREE_INPUT_RING_TYPE_TX UINT32_C(0x1)
+ /* RX Ring (RR) */
+ #define HWRM_RING_FREE_INPUT_RING_TYPE_RX UINT32_C(0x2)
+ /* RoCE Notification Completion Ring (ROCE_CR) */
+ #define HWRM_RING_FREE_INPUT_RING_TYPE_ROCE_CMPL UINT32_C(0x3)
+ /* RX Aggregation Ring */
+ #define HWRM_RING_FREE_INPUT_RING_TYPE_RX_AGG UINT32_C(0x4)
+ /* Notification Queue */
+ #define HWRM_RING_FREE_INPUT_RING_TYPE_NQ UINT32_C(0x5)
+ #define HWRM_RING_FREE_INPUT_RING_TYPE_LAST \
+ HWRM_RING_FREE_INPUT_RING_TYPE_NQ
+ uint8_t unused_0;
+ /* Physical number of ring allocated. */
+ uint16_t ring_id;
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_ring_free_output (size:128b/16B) */
+struct hwrm_ring_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_ring_cmpl_ring_qaggint_params *
+ **************************************/
+
+
+/* hwrm_ring_cmpl_ring_qaggint_params_input (size:192b/24B) */
+struct hwrm_ring_cmpl_ring_qaggint_params_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Physical number of completion ring. */
+ uint16_t ring_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_ring_cmpl_ring_qaggint_params_output (size:256b/32B) */
+struct hwrm_ring_cmpl_ring_qaggint_params_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint16_t flags;
+ /*
+ * When this bit is set to '1', interrupt max
+ * timer is reset whenever a completion is received.
+ */
+ #define HWRM_RING_CMPL_RING_QAGGINT_PARAMS_OUTPUT_FLAGS_TIMER_RESET \
+ UINT32_C(0x1)
+ /*
+ * When this bit is set to '1', ring idle mode
+ * aggregation will be enabled.
+ */
+ #define HWRM_RING_CMPL_RING_QAGGINT_PARAMS_OUTPUT_FLAGS_RING_IDLE \
+ UINT32_C(0x2)
+ /*
+ * Number of completions to aggregate before DMA
+ * during the normal mode.
+ */
+ uint16_t num_cmpl_dma_aggr;
+ /*
+ * Number of completions to aggregate before DMA
+ * during the interrupt mode.
+ */
+ uint16_t num_cmpl_dma_aggr_during_int;
+ /*
+ * Timer in unit of 80-nsec used to aggregate completions before
+ * DMA during the normal mode (not in interrupt mode).
+ */
+ uint16_t cmpl_aggr_dma_tmr;
+ /*
+ * Timer in unit of 80-nsec used to aggregate completions before
+ * DMA during the interrupt mode.
+ */
+ uint16_t cmpl_aggr_dma_tmr_during_int;
+ /* Minimum time (in unit of 80-nsec) between two interrupts. */
+ uint16_t int_lat_tmr_min;
+ /*
+ * Maximum wait time (in unit of 80-nsec) spent aggregating
+ * completions before signaling the interrupt after the
+ * interrupt is enabled.
+ */
+ uint16_t int_lat_tmr_max;
+ /*
+ * Minimum number of completions aggregated before signaling
+ * an interrupt.
+ */
+ uint16_t num_cmpl_aggr_int;
+ uint8_t unused_0[7];
+ /*
+ * 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_ring_cmpl_ring_cfg_aggint_params *
+ *****************************************/
+
+
+/* hwrm_ring_cmpl_ring_cfg_aggint_params_input (size:320b/40B) */
+struct hwrm_ring_cmpl_ring_cfg_aggint_params_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Physical number of completion ring. */
+ uint16_t ring_id;
+ uint16_t flags;
+ /*
+ * When this bit is set to '1', interrupt latency max
+ * timer is reset whenever a completion is received.
+ */
+ #define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET \
+ UINT32_C(0x1)
+ /*
+ * When this bit is set to '1', ring idle mode
+ * aggregation will be enabled.
+ */
+ #define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_RING_IDLE \
+ UINT32_C(0x2)
+ /*
+ * Set this flag to 1 when configuring parameters on a
+ * notification queue. Set this flag to 0 when configuring
+ * parameters on a completion queue.
+ */
+ #define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_IS_NQ \
+ UINT32_C(0x4)
+ /*
+ * Number of completions to aggregate before DMA
+ * during the normal mode.
+ */
+ uint16_t num_cmpl_dma_aggr;
+ /*
+ * Number of completions to aggregate before DMA
+ * during the interrupt mode.
+ */
+ uint16_t num_cmpl_dma_aggr_during_int;
+ /*
+ * Timer in unit of 80-nsec used to aggregate completions before
+ * DMA during the normal mode (not in interrupt mode).
+ */
+ uint16_t cmpl_aggr_dma_tmr;
+ /*
+ * Timer in unit of 80-nsec used to aggregate completions before
+ * DMA during the interrupt mode.
+ */
+ uint16_t cmpl_aggr_dma_tmr_during_int;
+ /* Minimum time (in unit of 80-nsec) between two interrupts. */
+ uint16_t int_lat_tmr_min;
+ /*
+ * Maximum wait time (in unit of 80-nsec) spent aggregating
+ * cmpls before signaling the interrupt after the
+ * interrupt is enabled.
+ */
+ uint16_t int_lat_tmr_max;
+ /*
+ * Minimum number of completions aggregated before signaling
+ * an interrupt.
+ */
+ uint16_t num_cmpl_aggr_int;
+ /*
+ * Bitfield that indicates which parameters are to be applied. Only
+ * required when configuring devices with notification queues, and
+ * used in that case to set certain parameters on completion queues
+ * and others on notification queues.
+ */
+ uint16_t enables;
+ /*
+ * This bit must be '1' for the num_cmpl_dma_aggr field to be
+ * configured.
+ */
+ #define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_NUM_CMPL_DMA_AGGR \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the num_cmpl_dma_aggr_during_int field to be
+ * configured.
+ */
+ #define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_NUM_CMPL_DMA_AGGR_DURING_INT \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the cmpl_aggr_dma_tmr field to be
+ * configured.
+ */
+ #define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_CMPL_AGGR_DMA_TMR \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the int_lat_tmr_min field to be
+ * configured.
+ */
+ #define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_INT_LAT_TMR_MIN \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the int_lat_tmr_max field to be
+ * configured.
+ */
+ #define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_INT_LAT_TMR_MAX \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the num_cmpl_aggr_int field to be
+ * configured.
+ */
+ #define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_NUM_CMPL_AGGR_INT \
+ UINT32_C(0x20)
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_ring_cmpl_ring_cfg_aggint_params_output (size:128b/16B) */
+struct hwrm_ring_cmpl_ring_cfg_aggint_params_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_ring_reset *
+ *******************/
+
+
+/* hwrm_ring_reset_input (size:192b/24B) */
+struct hwrm_ring_reset_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Ring Type. */
+ uint8_t ring_type;
+ /* L2 Completion Ring (CR) */
+ #define HWRM_RING_RESET_INPUT_RING_TYPE_L2_CMPL UINT32_C(0x0)
+ /* TX Ring (TR) */
+ #define HWRM_RING_RESET_INPUT_RING_TYPE_TX UINT32_C(0x1)
+ /* RX Ring (RR) */
+ #define HWRM_RING_RESET_INPUT_RING_TYPE_RX UINT32_C(0x2)
+ /* RoCE Notification Completion Ring (ROCE_CR) */
+ #define HWRM_RING_RESET_INPUT_RING_TYPE_ROCE_CMPL UINT32_C(0x3)
+ #define HWRM_RING_RESET_INPUT_RING_TYPE_LAST \
+ HWRM_RING_RESET_INPUT_RING_TYPE_ROCE_CMPL
+ uint8_t unused_0;
+ /* Physical number of the ring. */
+ uint16_t ring_id;
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_ring_reset_output (size:128b/16B) */
+struct hwrm_ring_reset_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_ring_grp_alloc *
+ ***********************/
+
+
+/* hwrm_ring_grp_alloc_input (size:192b/24B) */
+struct hwrm_ring_grp_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This value identifies the CR associated with the ring
+ * group.
+ */
+ uint16_t cr;
+ /*
+ * This value identifies the main RR associated with the ring
+ * group.
+ */
+ uint16_t rr;
+ /*
+ * This value identifies the aggregation RR associated with
+ * the ring group. If this value is 0xFF... (All Fs), then no
+ * Aggregation ring will be set.
+ */
+ uint16_t ar;
+ /*
+ * This value identifies the statistics context associated
+ * with the ring group.
+ */
+ uint16_t sc;
+} __attribute__((packed));
+
+/* hwrm_ring_grp_alloc_output (size:128b/16B) */
+struct hwrm_ring_grp_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * This is the ring group ID value. Use this value to program
+ * the default ring group for the VNIC or as table entries
+ * in an RSS/COS context.
+ */
+ uint32_t ring_group_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_ring_grp_free *
+ **********************/
+
+
+/* hwrm_ring_grp_free_input (size:192b/24B) */
+struct hwrm_ring_grp_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* This is the ring group ID value. */
+ uint32_t ring_group_id;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_ring_grp_free_output (size:128b/16B) */
+struct hwrm_ring_grp_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_l2_filter_alloc *
+ ****************************/
+
+
+/* hwrm_cfa_l2_filter_alloc_input (size:768b/96B) */
+struct hwrm_cfa_l2_filter_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * 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_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH \
+ UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_TX \
+ UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX \
+ UINT32_C(0x1)
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_LAST \
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX
+ /* Setting of this flag indicates the applicability to the loopback path. */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_LOOPBACK \
+ UINT32_C(0x2)
+ /*
+ * Setting of this flag indicates drop action. If this flag is not set,
+ * then it should be considered accept action.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_DROP \
+ UINT32_C(0x4)
+ /*
+ * If this flag is set, all t_l2_* fields are invalid
+ * and they should not be specified.
+ * If this flag is set, then l2_* fields refer to
+ * fields of outermost L2 header.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST \
+ UINT32_C(0x8)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the l2_addr field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the l2_addr_mask field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the l2_ovlan field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the l2_ovlan_mask field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the l2_ivlan field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the l2_ivlan_mask field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the t_l2_addr field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_ADDR \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the t_l2_addr_mask field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_ADDR_MASK \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the t_l2_ovlan field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_OVLAN \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the t_l2_ovlan_mask field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_OVLAN_MASK \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the t_l2_ivlan field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_IVLAN \
+ UINT32_C(0x400)
+ /*
+ * This bit must be '1' for the t_l2_ivlan_mask field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_IVLAN_MASK \
+ UINT32_C(0x800)
+ /*
+ * This bit must be '1' for the src_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE \
+ UINT32_C(0x1000)
+ /*
+ * This bit must be '1' for the src_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID \
+ UINT32_C(0x2000)
+ /*
+ * This bit must be '1' for the tunnel_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE \
+ UINT32_C(0x4000)
+ /*
+ * This bit must be '1' for the dst_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID \
+ UINT32_C(0x8000)
+ /*
+ * This bit must be '1' for the mirror_vnic_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID \
+ UINT32_C(0x10000)
+ /*
+ * This value sets the match value for the L2 MAC address.
+ * Destination MAC address for RX path.
+ * Source MAC address for TX path.
+ */
+ uint8_t l2_addr[6];
+ uint8_t unused_0[2];
+ /*
+ * This value sets the mask value for the L2 address.
+ * A value of 0 will mask the corresponding bit from
+ * compare.
+ */
+ uint8_t l2_addr_mask[6];
+ /* This value sets VLAN ID value for outer VLAN. */
+ uint16_t l2_ovlan;
+ /*
+ * This value sets the mask value for the ovlan id.
+ * A value of 0 will mask the corresponding bit from
+ * compare.
+ */
+ uint16_t l2_ovlan_mask;
+ /* This value sets VLAN ID value for inner VLAN. */
+ uint16_t l2_ivlan;
+ /*
+ * This value sets the mask value for the ivlan id.
+ * A value of 0 will mask the corresponding bit from
+ * compare.
+ */
+ uint16_t l2_ivlan_mask;
+ uint8_t unused_1[2];
+ /*
+ * This value sets the match value for the tunnel
+ * L2 MAC address.
+ * Destination MAC address for RX path.
+ * Source MAC address for TX path.
+ */
+ uint8_t t_l2_addr[6];
+ uint8_t unused_2[2];
+ /*
+ * This value sets the mask value for the tunnel L2
+ * address.
+ * A value of 0 will mask the corresponding bit from
+ * compare.
+ */
+ uint8_t t_l2_addr_mask[6];
+ /* This value sets VLAN ID value for tunnel outer VLAN. */
+ uint16_t t_l2_ovlan;
+ /*
+ * This value sets the mask value for the tunnel ovlan id.
+ * A value of 0 will mask the corresponding bit from
+ * compare.
+ */
+ uint16_t t_l2_ovlan_mask;
+ /* This value sets VLAN ID value for tunnel inner VLAN. */
+ uint16_t t_l2_ivlan;
+ /*
+ * This value sets the mask value for the tunnel ivlan id.
+ * A value of 0 will mask the corresponding bit from
+ * compare.
+ */
+ uint16_t t_l2_ivlan_mask;
+ /* This value identifies the type of source of the packet. */
+ uint8_t src_type;
+ /* Network port */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_NPORT UINT32_C(0x0)
+ /* Physical function */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_PF UINT32_C(0x1)
+ /* Virtual function */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VF UINT32_C(0x2)
+ /* Virtual NIC of a function */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VNIC UINT32_C(0x3)
+ /* Embedded processor for CFA management */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_KONG UINT32_C(0x4)
+ /* Embedded processor for OOB management */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_APE UINT32_C(0x5)
+ /* Embedded processor for RoCE */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_BONO UINT32_C(0x6)
+ /* Embedded processor for network proxy functions */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG UINT32_C(0x7)
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_LAST \
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG
+ uint8_t unused_3;
+ /*
+ * This value is the id of the source.
+ * For a network port, it represents port_id.
+ * For a physical function, it represents fid.
+ * For a virtual function, it represents vf_id.
+ * For a vnic, it represents vnic_id.
+ * For embedded processors, this id is not valid.
+ *
+ * Notes:
+ * 1. The function ID is implied if it src_id is
+ * not provided for a src_type that is either
+ */
+ uint32_t src_id;
+ /* Tunnel Type. */
+ uint8_t tunnel_type;
+ /* Non-tunnel */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+ UINT32_C(0x0)
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Network Virtualization Generic Routing Encapsulation (NVGRE) */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+ UINT32_C(0x2)
+ /* Generic Routing Encapsulation (GRE) inside Ethernet payload */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE \
+ UINT32_C(0x3)
+ /* IP in IP */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP \
+ UINT32_C(0x4)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* Multi-Protocol Lable Switching (MPLS) */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS \
+ UINT32_C(0x6)
+ /* Stateless Transport Tunnel (STT) */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT \
+ UINT32_C(0x7)
+ /* Generic Routing Encapsulation (GRE) inside IP datagram payload */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE \
+ UINT32_C(0x8)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Any tunneled traffic */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+ UINT32_C(0xff)
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL
+ uint8_t unused_4;
+ /*
+ * If set, this value shall represent the
+ * Logical VNIC ID of the destination VNIC for the RX
+ * path and network port id of the destination port for
+ * the TX path.
+ */
+ uint16_t dst_id;
+ /*
+ * Logical VNIC ID of the VNIC where traffic is
+ * mirrored.
+ */
+ uint16_t mirror_vnic_id;
+ /*
+ * This hint is provided to help in placing
+ * the filter in the filter table.
+ */
+ uint8_t pri_hint;
+ /* No preference */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER \
+ UINT32_C(0x0)
+ /* Above the given filter */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER \
+ UINT32_C(0x1)
+ /* Below the given filter */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER \
+ UINT32_C(0x2)
+ /* As high as possible */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX \
+ UINT32_C(0x3)
+ /* As low as possible */
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN \
+ UINT32_C(0x4)
+ #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_LAST \
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN
+ uint8_t unused_5;
+ uint32_t unused_6;
+ /*
+ * This is the ID of the filter that goes along with
+ * the pri_hint.
+ *
+ * This field is valid only for the following values.
+ * 1 - Above the given filter
+ * 2 - Below the given filter
+ */
+ uint64_t l2_filter_id_hint;
+} __attribute__((packed));
+
+/* hwrm_cfa_l2_filter_alloc_output (size:192b/24B) */
+struct hwrm_cfa_l2_filter_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * This value identifies a set of CFA data structures used for an L2
+ * context.
+ */
+ uint64_t l2_filter_id;
+ /*
+ * This is the ID of the flow associated with this
+ * filter.
+ * This value shall be used to match and associate the
+ * flow identifier returned in completion records.
+ * A value of 0xFFFFFFFF shall indicate no flow id.
+ */
+ uint32_t flow_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_cfa_l2_filter_free *
+ ***************************/
+
+
+/* hwrm_cfa_l2_filter_free_input (size:192b/24B) */
+struct hwrm_cfa_l2_filter_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This value identifies a set of CFA data structures used for an L2
+ * context.
+ */
+ uint64_t l2_filter_id;
+} __attribute__((packed));
+
+/* hwrm_cfa_l2_filter_free_output (size:128b/16B) */
+struct hwrm_cfa_l2_filter_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_l2_filter_cfg *
+ **************************/
+
+
+/* hwrm_cfa_l2_filter_cfg_input (size:320b/40B) */
+struct hwrm_cfa_l2_filter_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * 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_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_TX UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX UINT32_C(0x1)
+ #define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_LAST \
+ HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX
+ /*
+ * Setting of this flag indicates drop action. If this flag is not set,
+ * then it should be considered accept action.
+ */
+ #define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_DROP UINT32_C(0x2)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the dst_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_DST_ID \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the new_mirror_vnic_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID \
+ UINT32_C(0x2)
+ /*
+ * This value identifies a set of CFA data structures used for an L2
+ * context.
+ */
+ uint64_t l2_filter_id;
+ /*
+ * If set, this value shall represent the
+ * Logical VNIC ID of the destination VNIC for the RX
+ * path and network port id of the destination port for
+ * the TX path.
+ */
+ uint32_t dst_id;
+ /*
+ * New Logical VNIC ID of the VNIC where traffic is
+ * mirrored.
+ */
+ uint32_t new_mirror_vnic_id;
+} __attribute__((packed));
+
+/* hwrm_cfa_l2_filter_cfg_output (size:128b/16B) */
+struct hwrm_cfa_l2_filter_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_l2_set_rx_mask *
+ ***************************/
+
+
+/* hwrm_cfa_l2_set_rx_mask_input (size:448b/56B) */
+struct hwrm_cfa_l2_set_rx_mask_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* VNIC ID */
+ uint32_t vnic_id;
+ uint32_t mask;
+ /*
+ * When this bit is '1', the function is requested to accept
+ * multi-cast packets specified by the multicast addr table.
+ */
+ #define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST \
+ UINT32_C(0x2)
+ /*
+ * When this bit is '1', the function is requested to accept
+ * all multi-cast packets.
+ */
+ #define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST \
+ UINT32_C(0x4)
+ /*
+ * When this bit is '1', the function is requested to accept
+ * broadcast packets.
+ */
+ #define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST \
+ UINT32_C(0x8)
+ /*
+ * When this bit is '1', the function is requested to be
+ * put in the promiscuous mode.
+ *
+ * The HWRM should accept any function to set up
+ * promiscuous mode.
+ *
+ * The HWRM shall follow the semantics below for the
+ * promiscuous mode support.
+ * # When partitioning is not enabled on a port
+ * (i.e. single PF on the port), then the PF shall
+ * be allowed to be in the promiscuous mode. When the
+ * PF is in the promiscuous mode, then it shall
+ * receive all host bound traffic on that port.
+ * # When partitioning is enabled on a port
+ * (i.e. multiple PFs per port) and a PF on that
+ * port is in the promiscuous mode, then the PF
+ * receives all traffic within that partition as
+ * identified by a unique identifier for the
+ * PF (e.g. S-Tag). If a unique outer VLAN
+ * for the PF is specified, then the setting of
+ * promiscuous mode on that PF shall result in the
+ * PF receiving all host bound traffic with matching
+ * outer VLAN.
+ * # A VF shall can be set in the promiscuous mode.
+ * In the promiscuous mode, the VF does not receive any
+ * traffic unless a unique outer VLAN for the
+ * VF is specified. If a unique outer VLAN
+ * for the VF is specified, then the setting of
+ * promiscuous mode on that VF shall result in the
+ * VF receiving all host bound traffic with the
+ * matching outer VLAN.
+ * # The HWRM shall allow the setting of promiscuous
+ * mode on a function independently from the
+ * promiscuous mode settings on other functions.
+ */
+ #define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS \
+ UINT32_C(0x10)
+ /*
+ * If this flag is set, the corresponding RX
+ * filters shall be set up to cover multicast/broadcast
+ * filters for the outermost Layer 2 destination MAC
+ * address field.
+ */
+ #define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_OUTERMOST \
+ UINT32_C(0x20)
+ /*
+ * If this flag is set, the corresponding RX
+ * filters shall be set up to cover multicast/broadcast
+ * filters for the VLAN-tagged packets that match the
+ * TPID and VID fields of VLAN tags in the VLAN tag
+ * table specified in this command.
+ */
+ #define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY \
+ UINT32_C(0x40)
+ /*
+ * If this flag is set, the corresponding RX
+ * filters shall be set up to cover multicast/broadcast
+ * filters for non-VLAN tagged packets and VLAN-tagged
+ * packets that match the TPID and VID fields of VLAN
+ * tags in the VLAN tag table specified in this command.
+ */
+ #define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN \
+ UINT32_C(0x80)
+ /*
+ * If this flag is set, the corresponding RX
+ * filters shall be set up to cover multicast/broadcast
+ * filters for non-VLAN tagged packets and VLAN-tagged
+ * packets matching any VLAN tag.
+ *
+ * If this flag is set, then the HWRM shall ignore
+ * VLAN tags specified in vlan_tag_tbl.
+ *
+ * If none of vlanonly, vlan_nonvlan, and anyvlan_nonvlan
+ * flags is set, then the HWRM shall ignore
+ * VLAN tags specified in vlan_tag_tbl.
+ *
+ * The HWRM client shall set at most one flag out of
+ * vlanonly, vlan_nonvlan, and anyvlan_nonvlan.
+ */
+ #define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN \
+ UINT32_C(0x100)
+ /* This is the address for mcast address tbl. */
+ uint64_t mc_tbl_addr;
+ /*
+ * This value indicates how many entries in mc_tbl are valid.
+ * Each entry is 6 bytes.
+ */
+ uint32_t num_mc_entries;
+ uint8_t unused_0[4];
+ /*
+ * This is the address for VLAN tag table.
+ * Each VLAN entry in the table is 4 bytes of a VLAN tag
+ * including TPID, PCP, DEI, and VID fields in network byte
+ * order.
+ */
+ uint64_t vlan_tag_tbl_addr;
+ /*
+ * This value indicates how many entries in vlan_tag_tbl are
+ * valid. Each entry is 4 bytes.
+ */
+ uint32_t num_vlan_tags;
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_l2_set_rx_mask_output (size:128b/16B) */
+struct hwrm_cfa_l2_set_rx_mask_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_l2_set_rx_mask_cmd_err (size:64b/8B) */
+struct hwrm_cfa_l2_set_rx_mask_cmd_err {
+ /*
+ * command specific error codes that goes to
+ * the cmd_err field in Common HWRM Error Response.
+ */
+ uint8_t code;
+ /* Unknown error */
+ #define HWRM_CFA_L2_SET_RX_MASK_CMD_ERR_CODE_UNKNOWN \
+ UINT32_C(0x0)
+ /* Unable to complete operation due to conflict with Ntuple Filter */
+ #define HWRM_CFA_L2_SET_RX_MASK_CMD_ERR_CODE_NTUPLE_FILTER_CONFLICT_ERR \
+ UINT32_C(0x1)
+ #define HWRM_CFA_L2_SET_RX_MASK_CMD_ERR_CODE_LAST \
+ HWRM_CFA_L2_SET_RX_MASK_CMD_ERR_CODE_NTUPLE_FILTER_CONFLICT_ERR
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/*******************************
+ * hwrm_cfa_vlan_antispoof_cfg *
+ *******************************/
+
+
+/* hwrm_cfa_vlan_antispoof_cfg_input (size:256b/32B) */
+struct hwrm_cfa_vlan_antispoof_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * Function ID of the function that is being configured.
+ * Only valid for a VF FID configured by the PF.
+ */
+ uint16_t fid;
+ uint8_t unused_0[2];
+ /* Number of VLAN entries in the vlan_tag_mask_tbl. */
+ uint32_t num_vlan_entries;
+ /*
+ * The vlan_tag_mask_tbl_addr is the DMA address of the VLAN
+ * antispoof table. Each table entry contains the 16-bit TPID
+ * (0x8100 or 0x88a8 only), 16-bit VLAN ID, and a 16-bit mask,
+ * all in network order to match hwrm_cfa_l2_set_rx_mask.
+ * For an individual VLAN entry, the mask value should be 0xfff
+ * for the 12-bit VLAN ID.
+ */
+ uint64_t vlan_tag_mask_tbl_addr;
+} __attribute__((packed));
+
+/* hwrm_cfa_vlan_antispoof_cfg_output (size:128b/16B) */
+struct hwrm_cfa_vlan_antispoof_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_vlan_antispoof_qcfg *
+ ********************************/
+
+
+/* hwrm_cfa_vlan_antispoof_qcfg_input (size:256b/32B) */
+struct hwrm_cfa_vlan_antispoof_qcfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * Function ID of the function that is being queried.
+ * Only valid for a VF FID queried by the PF.
+ */
+ uint16_t fid;
+ uint8_t unused_0[2];
+ /*
+ * Maximum number of VLAN entries the firmware is allowed to DMA
+ * to vlan_tag_mask_tbl.
+ */
+ uint32_t max_vlan_entries;
+ /*
+ * The vlan_tag_mask_tbl_addr is the DMA address of the VLAN
+ * antispoof table to which firmware will DMA to. Each table
+ * entry will contain the 16-bit TPID (0x8100 or 0x88a8 only),
+ * 16-bit VLAN ID, and a 16-bit mask, all in network order to
+ * match hwrm_cfa_l2_set_rx_mask. For an individual VLAN entry,
+ * the mask value should be 0xfff for the 12-bit VLAN ID.
+ */
+ uint64_t vlan_tag_mask_tbl_addr;
+} __attribute__((packed));
+
+/* hwrm_cfa_vlan_antispoof_qcfg_output (size:128b/16B) */
+struct hwrm_cfa_vlan_antispoof_qcfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Number of valid entries DMAd by firmware to vlan_tag_mask_tbl. */
+ uint32_t num_vlan_entries;
+ uint8_t unused_0[3];
+ /*
+ * 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_cfa_tunnel_filter_alloc *
+ ********************************/
+
+
+/* hwrm_cfa_tunnel_filter_alloc_input (size:704b/88B) */
+struct hwrm_cfa_tunnel_filter_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /* Setting of this flag indicates the applicability to the loopback path. */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_FLAGS_LOOPBACK \
+ UINT32_C(0x1)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the l2_filter_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the l2_addr field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the l2_ivlan field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the l3_addr field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_L3_ADDR \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the l3_addr_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_L3_ADDR_TYPE \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the t_l3_addr_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_T_L3_ADDR_TYPE \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the t_l3_addr field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_T_L3_ADDR \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the tunnel_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the vni field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_VNI \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the dst_vnic_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_DST_VNIC_ID \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the mirror_vnic_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID \
+ UINT32_C(0x400)
+ /*
+ * This value identifies a set of CFA data structures used for an L2
+ * context.
+ */
+ uint64_t l2_filter_id;
+ /*
+ * This value sets the match value for the inner L2
+ * MAC address.
+ * Destination MAC address for RX path.
+ * Source MAC address for TX path.
+ */
+ uint8_t l2_addr[6];
+ /*
+ * This value sets VLAN ID value for inner VLAN.
+ * Only 12-bits of VLAN ID are used in setting the filter.
+ */
+ uint16_t l2_ivlan;
+ /*
+ * The value of inner destination IP address to be used in filtering.
+ * For IPv4, first four bytes represent the IP address.
+ */
+ uint32_t l3_addr[4];
+ /*
+ * The value of tunnel destination IP address to be used in filtering.
+ * For IPv4, first four bytes represent the IP address.
+ */
+ uint32_t t_l3_addr[4];
+ /*
+ * This value indicates the type of inner IP address.
+ * 4 - IPv4
+ * 6 - IPv6
+ * All others are invalid.
+ */
+ uint8_t l3_addr_type;
+ /*
+ * This value indicates the type of tunnel IP address.
+ * 4 - IPv4
+ * 6 - IPv6
+ * All others are invalid.
+ */
+ uint8_t t_l3_addr_type;
+ /* Tunnel Type. */
+ uint8_t tunnel_type;
+ /* Non-tunnel */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+ UINT32_C(0x0)
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Network Virtualization Generic Routing Encapsulation (NVGRE) */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+ UINT32_C(0x2)
+ /* Generic Routing Encapsulation (GRE) inside Ethernet payload */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE \
+ UINT32_C(0x3)
+ /* IP in IP */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP \
+ UINT32_C(0x4)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* Multi-Protocol Lable Switching (MPLS) */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS \
+ UINT32_C(0x6)
+ /* Stateless Transport Tunnel (STT) */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT \
+ UINT32_C(0x7)
+ /* Generic Routing Encapsulation (GRE) inside IP datagram payload */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE \
+ UINT32_C(0x8)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Any tunneled traffic */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+ UINT32_C(0xff)
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL
+ /*
+ * tunnel_flags allows the user to indicate the tunnel tag detection
+ * for the tunnel type specified in tunnel_type.
+ */
+ uint8_t tunnel_flags;
+ /*
+ * If the tunnel_type is geneve, then this bit indicates if we
+ * need to match the geneve OAM packet.
+ * If the tunnel_type is nvgre or gre, then this bit indicates if
+ * we need to detect checksum present bit in geneve header.
+ * If the tunnel_type is mpls, then this bit indicates if we need
+ * to match mpls packet with explicit IPV4/IPV6 null header.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_FLAGS_TUN_FLAGS_OAM_CHECKSUM_EXPLHDR \
+ UINT32_C(0x1)
+ /*
+ * If the tunnel_type is geneve, then this bit indicates if we
+ * need to detect the critical option bit set in the oam packet.
+ * If the tunnel_type is nvgre or gre, then this bit indicates
+ * if we need to match nvgre packets with key present bit set in
+ * gre header.
+ * If the tunnel_type is mpls, then this bit indicates if we
+ * need to match mpls packet with S bit from inner/second label.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_FLAGS_TUN_FLAGS_CRITICAL_OPT_S1 \
+ UINT32_C(0x2)
+ /*
+ * If the tunnel_type is geneve, then this bit indicates if we
+ * need to match geneve packet with extended header bit set in
+ * geneve header.
+ * If the tunnel_type is nvgre or gre, then this bit indicates
+ * if we need to match nvgre packets with sequence number
+ * present bit set in gre header.
+ * If the tunnel_type is mpls, then this bit indicates if we
+ * need to match mpls packet with S bit from out/first label.
+ */
+ #define HWRM_CFA_TUNNEL_FILTER_ALLOC_INPUT_TUNNEL_FLAGS_TUN_FLAGS_EXTHDR_SEQNUM_S0 \
+ UINT32_C(0x4)
+ /*
+ * Virtual Network Identifier (VNI). Only valid with
+ * tunnel_types VXLAN, NVGRE, and Geneve.
+ * Only lower 24-bits of VNI field are used
+ * in setting up the filter.
+ */
+ uint32_t vni;
+ /* Logical VNIC ID of the destination VNIC. */
+ uint32_t dst_vnic_id;
+ /*
+ * Logical VNIC ID of the VNIC where traffic is
+ * mirrored.
+ */
+ uint32_t mirror_vnic_id;
+} __attribute__((packed));
+
+/* hwrm_cfa_tunnel_filter_alloc_output (size:192b/24B) */
+struct hwrm_cfa_tunnel_filter_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This value is an opaque id into CFA data structures. */
+ uint64_t tunnel_filter_id;
+ /*
+ * This is the ID of the flow associated with this
+ * filter.
+ * This value shall be used to match and associate the
+ * flow identifier returned in completion records.
+ * A value of 0xFFFFFFFF shall indicate no flow id.
+ */
+ uint32_t flow_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_cfa_tunnel_filter_free *
+ *******************************/
+
+
+/* hwrm_cfa_tunnel_filter_free_input (size:192b/24B) */
+struct hwrm_cfa_tunnel_filter_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* This value is an opaque id into CFA data structures. */
+ uint64_t tunnel_filter_id;
+} __attribute__((packed));
+
+/* hwrm_cfa_tunnel_filter_free_output (size:128b/16B) */
+struct hwrm_cfa_tunnel_filter_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_redirect_tunnel_type_alloc *
+ ***************************************/
+
+
+/* hwrm_cfa_redirect_tunnel_type_alloc_input (size:192b/24B) */
+struct hwrm_cfa_redirect_tunnel_type_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* The destination function id, to whom the traffic is redirected. */
+ uint16_t dest_fid;
+ /* Tunnel Type. */
+ uint8_t tunnel_type;
+ /* Non-tunnel */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+ UINT32_C(0x0)
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Network Virtualization Generic Routing Encapsulation (NVGRE) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+ UINT32_C(0x2)
+ /* Generic Routing Encapsulation (GRE) inside Ethernet payload */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_L2GRE \
+ UINT32_C(0x3)
+ /* IP in IP */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_IPIP \
+ UINT32_C(0x4)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* Multi-Protocol Lable Switching (MPLS) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_MPLS \
+ UINT32_C(0x6)
+ /* Stateless Transport Tunnel (STT) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_STT \
+ UINT32_C(0x7)
+ /* Generic Routing Encapsulation (GRE) inside IP datagram payload */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_IPGRE \
+ UINT32_C(0x8)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Enhance Generic Routing Encapsulation (GRE version 1) inside IP datagram payload */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_IPGRE_V1 \
+ UINT32_C(0xa)
+ /* Any tunneled traffic */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+ UINT32_C(0xff)
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL
+ /* Tunnel alloc flags. */
+ uint8_t flags;
+ /* Setting of this flag indicates modify existing redirect tunnel to new destination function ID. */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC_INPUT_FLAGS_MODIFY_DST \
+ UINT32_C(0x1)
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_redirect_tunnel_type_alloc_output (size:128b/16B) */
+struct hwrm_cfa_redirect_tunnel_type_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_redirect_tunnel_type_free *
+ **************************************/
+
+
+/* hwrm_cfa_redirect_tunnel_type_free_input (size:192b/24B) */
+struct hwrm_cfa_redirect_tunnel_type_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* The destination function id, to whom the traffic is redirected. */
+ uint16_t dest_fid;
+ /* Tunnel Type. */
+ uint8_t tunnel_type;
+ /* Non-tunnel */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_NONTUNNEL \
+ UINT32_C(0x0)
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Network Virtualization Generic Routing Encapsulation (NVGRE) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_NVGRE \
+ UINT32_C(0x2)
+ /* Generic Routing Encapsulation (GRE) inside Ethernet payload */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_L2GRE \
+ UINT32_C(0x3)
+ /* IP in IP */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_IPIP \
+ UINT32_C(0x4)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* Multi-Protocol Lable Switching (MPLS) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_MPLS \
+ UINT32_C(0x6)
+ /* Stateless Transport Tunnel (STT) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_STT \
+ UINT32_C(0x7)
+ /* Generic Routing Encapsulation (GRE) inside IP datagram payload */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_IPGRE \
+ UINT32_C(0x8)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Enhance Generic Routing Encapsulation (GRE version 1) inside IP datagram payload */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_IPGRE_V1 \
+ UINT32_C(0xa)
+ /* Any tunneled traffic */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+ UINT32_C(0xff)
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE_INPUT_TUNNEL_TYPE_ANYTUNNEL
+ uint8_t unused_0[5];
+} __attribute__((packed));
+
+/* hwrm_cfa_redirect_tunnel_type_free_output (size:128b/16B) */
+struct hwrm_cfa_redirect_tunnel_type_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_redirect_tunnel_type_info *
+ **************************************/
+
+
+/* hwrm_cfa_redirect_tunnel_type_info_input (size:192b/24B) */
+struct hwrm_cfa_redirect_tunnel_type_info_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* The source function id. */
+ uint16_t src_fid;
+ /* Tunnel Type. */
+ uint8_t tunnel_type;
+ /* Non-tunnel */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_NONTUNNEL \
+ UINT32_C(0x0)
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Network Virtualization Generic Routing Encapsulation (NVGRE) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_NVGRE \
+ UINT32_C(0x2)
+ /* Generic Routing Encapsulation (GRE) inside Ethernet payload */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_L2GRE \
+ UINT32_C(0x3)
+ /* IP in IP */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_IPIP \
+ UINT32_C(0x4)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* Multi-Protocol Lable Switching (MPLS) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_MPLS \
+ UINT32_C(0x6)
+ /* Stateless Transport Tunnel (STT) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_STT \
+ UINT32_C(0x7)
+ /* Generic Routing Encapsulation (GRE) inside IP datagram payload */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_IPGRE \
+ UINT32_C(0x8)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Enhance Generic Routing Encapsulation (GRE version 1) inside IP datagram payload */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_IPGRE_V1 \
+ UINT32_C(0xa)
+ /* Any tunneled traffic */
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+ UINT32_C(0xff)
+ #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_CFA_REDIRECT_TUNNEL_TYPE_INFO_INPUT_TUNNEL_TYPE_ANYTUNNEL
+ uint8_t unused_0[5];
+} __attribute__((packed));
+
+/* hwrm_cfa_redirect_tunnel_type_info_output (size:128b/16B) */
+struct hwrm_cfa_redirect_tunnel_type_info_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* The destination function id, to whom the traffic is redirected. */
+ uint16_t dest_fid;
+ uint8_t unused_0[5];
+ /*
+ * 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_vxlan_ipv4_hdr (size:128b/16B) */
+struct hwrm_vxlan_ipv4_hdr {
+ /* IPv4 version and header length. */
+ uint8_t ver_hlen;
+ /* IPv4 header length */
+ #define HWRM_VXLAN_IPV4_HDR_VER_HLEN_HEADER_LENGTH_MASK UINT32_C(0xf)
+ #define HWRM_VXLAN_IPV4_HDR_VER_HLEN_HEADER_LENGTH_SFT 0
+ /* Version */
+ #define HWRM_VXLAN_IPV4_HDR_VER_HLEN_VERSION_MASK UINT32_C(0xf0)
+ #define HWRM_VXLAN_IPV4_HDR_VER_HLEN_VERSION_SFT 4
+ /* IPv4 type of service. */
+ uint8_t tos;
+ /* IPv4 identification. */
+ uint16_t ip_id;
+ /* IPv4 flags and offset. */
+ uint16_t flags_frag_offset;
+ /* IPv4 TTL. */
+ uint8_t ttl;
+ /* IPv4 protocol. */
+ uint8_t protocol;
+ /* IPv4 source address. */
+ uint32_t src_ip_addr;
+ /* IPv4 destination address. */
+ uint32_t dest_ip_addr;
+} __attribute__((packed));
+
+/* hwrm_vxlan_ipv6_hdr (size:320b/40B) */
+struct hwrm_vxlan_ipv6_hdr {
+ /* IPv6 version, traffic class and flow label. */
+ uint32_t ver_tc_flow_label;
+ /* IPv6 version shift */
+ #define HWRM_VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_VER_SFT \
+ UINT32_C(0x1c)
+ /* IPv6 version mask */
+ #define HWRM_VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_VER_MASK \
+ UINT32_C(0xf0000000)
+ /* IPv6 TC shift */
+ #define HWRM_VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_TC_SFT \
+ UINT32_C(0x14)
+ /* IPv6 TC mask */
+ #define HWRM_VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_TC_MASK \
+ UINT32_C(0xff00000)
+ /* IPv6 flow label shift */
+ #define HWRM_VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_FLOW_LABEL_SFT \
+ UINT32_C(0x0)
+ /* IPv6 flow label mask */
+ #define HWRM_VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_FLOW_LABEL_MASK \
+ UINT32_C(0xfffff)
+ #define HWRM_VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_LAST \
+ HWRM_VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_FLOW_LABEL_MASK
+ /* IPv6 payload length. */
+ uint16_t payload_len;
+ /* IPv6 next header. */
+ uint8_t next_hdr;
+ /* IPv6 TTL. */
+ uint8_t ttl;
+ /* IPv6 source address. */
+ uint32_t src_ip_addr[4];
+ /* IPv6 destination address. */
+ uint32_t dest_ip_addr[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_encap_data_vxlan (size:576b/72B) */
+struct hwrm_cfa_encap_data_vxlan {
+ /* Source MAC address. */
+ uint8_t src_mac_addr[6];
+ /* reserved. */
+ uint16_t unused_0;
+ /* Destination MAC address. */
+ uint8_t dst_mac_addr[6];
+ /* Number of VLAN tags. */
+ uint8_t num_vlan_tags;
+ /* reserved. */
+ uint8_t unused_1;
+ /* Outer VLAN TPID. */
+ uint16_t ovlan_tpid;
+ /* Outer VLAN TCI. */
+ uint16_t ovlan_tci;
+ /* Inner VLAN TPID. */
+ uint16_t ivlan_tpid;
+ /* Inner VLAN TCI. */
+ uint16_t ivlan_tci;
+ /* L3 header fields. */
+ uint32_t l3[10];
+ /* IP version mask. */
+ #define HWRM_CFA_ENCAP_DATA_VXLAN_L3_VER_MASK UINT32_C(0xf)
+ /* IP version 4. */
+ #define HWRM_CFA_ENCAP_DATA_VXLAN_L3_VER_IPV4 UINT32_C(0x4)
+ /* IP version 6. */
+ #define HWRM_CFA_ENCAP_DATA_VXLAN_L3_VER_IPV6 UINT32_C(0x6)
+ #define HWRM_CFA_ENCAP_DATA_VXLAN_L3_LAST \
+ HWRM_CFA_ENCAP_DATA_VXLAN_L3_VER_IPV6
+ /* UDP source port. */
+ uint16_t src_port;
+ /* UDP destination port. */
+ uint16_t dst_port;
+ /* VXLAN Network Identifier. */
+ uint32_t vni;
+} __attribute__((packed));
+
+/*******************************
+ * hwrm_cfa_encap_record_alloc *
+ *******************************/
+
+
+/* hwrm_cfa_encap_record_alloc_input (size:832b/104B) */
+struct hwrm_cfa_encap_record_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /* Setting of this flag indicates the applicability to the loopback path. */
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_FLAGS_LOOPBACK \
+ UINT32_C(0x1)
+ /* Encapsulation Type. */
+ uint8_t encap_type;
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_ENCAP_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Network Virtualization Generic Routing Encapsulation (NVGRE) */
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_ENCAP_TYPE_NVGRE \
+ UINT32_C(0x2)
+ /* Generic Routing Encapsulation (GRE) after inside Ethernet payload */
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_ENCAP_TYPE_L2GRE \
+ UINT32_C(0x3)
+ /* IP in IP */
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_ENCAP_TYPE_IPIP \
+ UINT32_C(0x4)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_ENCAP_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* Multi-Protocol Lable Switching (MPLS) */
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_ENCAP_TYPE_MPLS \
+ UINT32_C(0x6)
+ /* VLAN */
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_ENCAP_TYPE_VLAN \
+ UINT32_C(0x7)
+ /* Generic Routing Encapsulation (GRE) inside IP datagram payload */
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_ENCAP_TYPE_IPGRE \
+ UINT32_C(0x8)
+ #define HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_ENCAP_TYPE_LAST \
+ HWRM_CFA_ENCAP_RECORD_ALLOC_INPUT_ENCAP_TYPE_IPGRE
+ uint8_t unused_0[3];
+ /* This value is encap data used for the given encap type. */
+ uint32_t encap_data[20];
+} __attribute__((packed));
+
+/* hwrm_cfa_encap_record_alloc_output (size:128b/16B) */
+struct hwrm_cfa_encap_record_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This value is an opaque id into CFA data structures. */
+ uint32_t encap_record_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_cfa_encap_record_free *
+ ******************************/
+
+
+/* hwrm_cfa_encap_record_free_input (size:192b/24B) */
+struct hwrm_cfa_encap_record_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* This value is an opaque id into CFA data structures. */
+ uint32_t encap_record_id;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_encap_record_free_output (size:128b/16B) */
+struct hwrm_cfa_encap_record_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_ntuple_filter_alloc *
+ ********************************/
+
+
+/* hwrm_cfa_ntuple_filter_alloc_input (size:1024b/128B) */
+struct hwrm_cfa_ntuple_filter_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /* Setting of this flag indicates the applicability to the loopback path. */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_LOOPBACK \
+ UINT32_C(0x1)
+ /*
+ * Setting of this flag indicates drop action. If this flag is not set,
+ * then it should be considered accept action.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP \
+ UINT32_C(0x2)
+ /*
+ * Setting of this flag indicates that a meter is expected to be attached
+ * to this flow. This hint can be used when choosing the action record
+ * format required for the flow.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_METER \
+ UINT32_C(0x4)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the l2_filter_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the ethertype field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_ETHERTYPE \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the tunnel_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the src_macaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_MACADDR \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the ipaddr_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_IPADDR_TYPE \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the src_ipaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_IPADDR \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the src_ipaddr_mask field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_IPADDR_MASK \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the dst_ipaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_IPADDR \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the dst_ipaddr_mask field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_IPADDR_MASK \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the ip_protocol field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_IP_PROTOCOL \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the src_port field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_PORT \
+ UINT32_C(0x400)
+ /*
+ * This bit must be '1' for the src_port_mask field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_SRC_PORT_MASK \
+ UINT32_C(0x800)
+ /*
+ * This bit must be '1' for the dst_port field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_PORT \
+ UINT32_C(0x1000)
+ /*
+ * This bit must be '1' for the dst_port_mask field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_PORT_MASK \
+ UINT32_C(0x2000)
+ /*
+ * This bit must be '1' for the pri_hint field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_PRI_HINT \
+ UINT32_C(0x4000)
+ /*
+ * This bit must be '1' for the ntuple_filter_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_NTUPLE_FILTER_ID \
+ UINT32_C(0x8000)
+ /*
+ * This bit must be '1' for the dst_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_ID \
+ UINT32_C(0x10000)
+ /*
+ * This bit must be '1' for the mirror_vnic_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID \
+ UINT32_C(0x20000)
+ /*
+ * This bit must be '1' for the dst_macaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_DST_MACADDR \
+ UINT32_C(0x40000)
+ /*
+ * This value identifies a set of CFA data structures used for an L2
+ * context.
+ */
+ uint64_t l2_filter_id;
+ /*
+ * This value indicates the source MAC address in
+ * the Ethernet header.
+ */
+ uint8_t src_macaddr[6];
+ /* This value indicates the ethertype in the Ethernet header. */
+ uint16_t ethertype;
+ /*
+ * This value indicates the type of IP address.
+ * 4 - IPv4
+ * 6 - IPv6
+ * All others are invalid.
+ */
+ uint8_t ip_addr_type;
+ /* invalid */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_UNKNOWN \
+ UINT32_C(0x0)
+ /* IPv4 */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV4 \
+ UINT32_C(0x4)
+ /* IPv6 */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV6 \
+ UINT32_C(0x6)
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_LAST \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV6
+ /*
+ * The value of protocol filed in IP header.
+ * Applies to UDP and TCP traffic.
+ * 6 - TCP
+ * 17 - UDP
+ */
+ uint8_t ip_protocol;
+ /* invalid */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_PROTOCOL_UNKNOWN \
+ UINT32_C(0x0)
+ /* TCP */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_PROTOCOL_TCP \
+ UINT32_C(0x6)
+ /* UDP */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_PROTOCOL_UDP \
+ UINT32_C(0x11)
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_PROTOCOL_LAST \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_PROTOCOL_UDP
+ /*
+ * If set, this value shall represent the
+ * Logical VNIC ID of the destination VNIC for the RX
+ * path and network port id of the destination port for
+ * the TX path.
+ */
+ uint16_t dst_id;
+ /*
+ * Logical VNIC ID of the VNIC where traffic is
+ * mirrored.
+ */
+ uint16_t mirror_vnic_id;
+ /*
+ * This value indicates the tunnel type for this filter.
+ * If this field is not specified, then the filter shall
+ * apply to both non-tunneled and tunneled packets.
+ * If this field conflicts with the tunnel_type specified
+ * in the l2_filter_id, then the HWRM shall return an
+ * error for this command.
+ */
+ uint8_t tunnel_type;
+ /* Non-tunnel */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+ UINT32_C(0x0)
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Network Virtualization Generic Routing Encapsulation (NVGRE) */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+ UINT32_C(0x2)
+ /* Generic Routing Encapsulation (GRE) inside Ethernet payload */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE \
+ UINT32_C(0x3)
+ /* IP in IP */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP \
+ UINT32_C(0x4)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* Multi-Protocol Lable Switching (MPLS) */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS \
+ UINT32_C(0x6)
+ /* Stateless Transport Tunnel (STT) */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT \
+ UINT32_C(0x7)
+ /* Generic Routing Encapsulation (GRE) inside IP datagram payload */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE \
+ UINT32_C(0x8)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Any tunneled traffic */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+ UINT32_C(0xff)
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL
+ /*
+ * This hint is provided to help in placing
+ * the filter in the filter table.
+ */
+ uint8_t pri_hint;
+ /* No preference */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER \
+ UINT32_C(0x0)
+ /* Above the given filter */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE \
+ UINT32_C(0x1)
+ /* Below the given filter */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_PRI_HINT_BELOW \
+ UINT32_C(0x2)
+ /* As high as possible */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_PRI_HINT_HIGHEST \
+ UINT32_C(0x3)
+ /* As low as possible */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_PRI_HINT_LOWEST \
+ UINT32_C(0x4)
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_PRI_HINT_LAST \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_PRI_HINT_LOWEST
+ /*
+ * The value of source IP address to be used in filtering.
+ * For IPv4, first four bytes represent the IP address.
+ */
+ uint32_t src_ipaddr[4];
+ /*
+ * The value of source IP address mask to be used in
+ * filtering.
+ * For IPv4, first four bytes represent the IP address mask.
+ */
+ uint32_t src_ipaddr_mask[4];
+ /*
+ * The value of destination IP address to be used in filtering.
+ * For IPv4, first four bytes represent the IP address.
+ */
+ uint32_t dst_ipaddr[4];
+ /*
+ * The value of destination IP address mask to be used in
+ * filtering.
+ * For IPv4, first four bytes represent the IP address mask.
+ */
+ uint32_t dst_ipaddr_mask[4];
+ /*
+ * The value of source port to be used in filtering.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t src_port;
+ /*
+ * The value of source port mask to be used in filtering.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t src_port_mask;
+ /*
+ * The value of destination port to be used in filtering.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t dst_port;
+ /*
+ * The value of destination port mask to be used in
+ * filtering.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t dst_port_mask;
+ /*
+ * This is the ID of the filter that goes along with
+ * the pri_hint.
+ */
+ uint64_t ntuple_filter_id_hint;
+} __attribute__((packed));
+
+/* hwrm_cfa_ntuple_filter_alloc_output (size:192b/24B) */
+struct hwrm_cfa_ntuple_filter_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This value is an opaque id into CFA data structures. */
+ uint64_t ntuple_filter_id;
+ /*
+ * This is the ID of the flow associated with this
+ * filter.
+ * This value shall be used to match and associate the
+ * flow identifier returned in completion records.
+ * A value of 0xFFFFFFFF shall indicate no flow id.
+ */
+ uint32_t flow_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_cfa_ntuple_filter_alloc_cmd_err (size:64b/8B) */
+struct hwrm_cfa_ntuple_filter_alloc_cmd_err {
+ /*
+ * command specific error codes that goes to
+ * the cmd_err field in Common HWRM Error Response.
+ */
+ uint8_t code;
+ /* Unknown error */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_CMD_ERR_CODE_UNKNOWN \
+ UINT32_C(0x0)
+ /* Unable to complete operation due to conflict with Rx Mask VLAN */
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_CMD_ERR_CODE_RX_MASK_VLAN_CONFLICT_ERR \
+ UINT32_C(0x1)
+ #define HWRM_CFA_NTUPLE_FILTER_ALLOC_CMD_ERR_CODE_LAST \
+ HWRM_CFA_NTUPLE_FILTER_ALLOC_CMD_ERR_CODE_RX_MASK_VLAN_CONFLICT_ERR
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/*******************************
+ * hwrm_cfa_ntuple_filter_free *
+ *******************************/
+
+
+/* hwrm_cfa_ntuple_filter_free_input (size:192b/24B) */
+struct hwrm_cfa_ntuple_filter_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* This value is an opaque id into CFA data structures. */
+ uint64_t ntuple_filter_id;
+} __attribute__((packed));
+
+/* hwrm_cfa_ntuple_filter_free_output (size:128b/16B) */
+struct hwrm_cfa_ntuple_filter_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_ntuple_filter_cfg *
+ ******************************/
+
+
+/* hwrm_cfa_ntuple_filter_cfg_input (size:384b/48B) */
+struct hwrm_cfa_ntuple_filter_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the new_dst_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_CFG_INPUT_ENABLES_NEW_DST_ID \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the new_mirror_vnic_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the new_meter_instance_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_CFG_INPUT_ENABLES_NEW_METER_INSTANCE_ID \
+ UINT32_C(0x4)
+ uint8_t unused_0[4];
+ /* This value is an opaque id into CFA data structures. */
+ uint64_t ntuple_filter_id;
+ /*
+ * If set, this value shall represent the new
+ * Logical VNIC ID of the destination VNIC for the RX
+ * path and new network port id of the destination port for
+ * the TX path.
+ */
+ uint32_t new_dst_id;
+ /*
+ * New Logical VNIC ID of the VNIC where traffic is
+ * mirrored.
+ */
+ uint32_t new_mirror_vnic_id;
+ /*
+ * New meter to attach to the flow. Specifying the
+ * invalid instance ID is used to remove any existing
+ * meter from the flow.
+ */
+ uint16_t new_meter_instance_id;
+ /*
+ * A value of 0xfff is considered invalid and implies the
+ * instance is not configured.
+ */
+ #define HWRM_CFA_NTUPLE_FILTER_CFG_INPUT_NEW_METER_INSTANCE_ID_INVALID \
+ UINT32_C(0xffff)
+ #define HWRM_CFA_NTUPLE_FILTER_CFG_INPUT_NEW_METER_INSTANCE_ID_LAST \
+ HWRM_CFA_NTUPLE_FILTER_CFG_INPUT_NEW_METER_INSTANCE_ID_INVALID
+ uint8_t unused_1[6];
+} __attribute__((packed));
+
+/* hwrm_cfa_ntuple_filter_cfg_output (size:128b/16B) */
+struct hwrm_cfa_ntuple_filter_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_em_flow_alloc *
+ **************************/
+
+
+/* hwrm_cfa_em_flow_alloc_input (size:896b/112B) */
+struct hwrm_cfa_em_flow_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /*
+ * 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_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_PATH UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_PATH_TX UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_PATH_RX UINT32_C(0x1)
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_PATH_LAST \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_PATH_RX
+ /*
+ * Setting of this flag indicates enabling of a byte counter for a given
+ * flow.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_BYTE_CTR UINT32_C(0x2)
+ /*
+ * Setting of this flag indicates enabling of a packet counter for a given
+ * flow.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_PKT_CTR UINT32_C(0x4)
+ /* Setting of this flag indicates de-capsulation action for the given flow. */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_DECAP UINT32_C(0x8)
+ /* Setting of this flag indicates encapsulation action for the given flow. */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_ENCAP UINT32_C(0x10)
+ /*
+ * Setting of this flag indicates drop action. If this flag is not set,
+ * then it should be considered accept action.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_DROP UINT32_C(0x20)
+ /*
+ * Setting of this flag indicates that a meter is expected to be attached
+ * to this flow. This hint can be used when choosing the action record
+ * format required for the flow.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_METER UINT32_C(0x40)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the l2_filter_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_L2_FILTER_ID \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the tunnel_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_TUNNEL_TYPE \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the tunnel_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_TUNNEL_ID \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the src_macaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_SRC_MACADDR \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the dst_macaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_MACADDR \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the ovlan_vid field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_OVLAN_VID \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the ivlan_vid field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_IVLAN_VID \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the ethertype field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_ETHERTYPE \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the src_ipaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_SRC_IPADDR \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the dst_ipaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_IPADDR \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the ipaddr_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_IPADDR_TYPE \
+ UINT32_C(0x400)
+ /*
+ * This bit must be '1' for the ip_protocol field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_IP_PROTOCOL \
+ UINT32_C(0x800)
+ /*
+ * This bit must be '1' for the src_port field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_SRC_PORT \
+ UINT32_C(0x1000)
+ /*
+ * This bit must be '1' for the dst_port field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_PORT \
+ UINT32_C(0x2000)
+ /*
+ * This bit must be '1' for the dst_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_DST_ID \
+ UINT32_C(0x4000)
+ /*
+ * This bit must be '1' for the mirror_vnic_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID \
+ UINT32_C(0x8000)
+ /*
+ * This bit must be '1' for the encap_record_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_ENCAP_RECORD_ID \
+ UINT32_C(0x10000)
+ /*
+ * This bit must be '1' for the meter_instance_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_METER_INSTANCE_ID \
+ UINT32_C(0x20000)
+ /*
+ * This value identifies a set of CFA data structures used for an L2
+ * context.
+ */
+ uint64_t l2_filter_id;
+ /* Tunnel Type. */
+ uint8_t tunnel_type;
+ /* Non-tunnel */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+ UINT32_C(0x0)
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Network Virtualization Generic Routing Encapsulation (NVGRE) */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+ UINT32_C(0x2)
+ /* Generic Routing Encapsulation (GRE) inside Ethernet payload */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_L2GRE \
+ UINT32_C(0x3)
+ /* IP in IP */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_IPIP \
+ UINT32_C(0x4)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* Multi-Protocol Lable Switching (MPLS) */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_MPLS \
+ UINT32_C(0x6)
+ /* Stateless Transport Tunnel (STT) */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_STT \
+ UINT32_C(0x7)
+ /* Generic Routing Encapsulation (GRE) inside IP datagram payload */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_IPGRE \
+ UINT32_C(0x8)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Any tunneled traffic */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+ UINT32_C(0xff)
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL
+ uint8_t unused_0[3];
+ /*
+ * Tunnel identifier.
+ * Virtual Network Identifier (VNI). Only valid with
+ * tunnel_types VXLAN, NVGRE, and Geneve.
+ * Only lower 24-bits of VNI field are used
+ * in setting up the filter.
+ */
+ uint32_t tunnel_id;
+ /*
+ * This value indicates the source MAC address in
+ * the Ethernet header.
+ */
+ uint8_t src_macaddr[6];
+ /* The meter instance to attach to the flow. */
+ uint16_t meter_instance_id;
+ /*
+ * A value of 0xfff is considered invalid and implies the
+ * instance is not configured.
+ */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_METER_INSTANCE_ID_INVALID \
+ UINT32_C(0xffff)
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_METER_INSTANCE_ID_LAST \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_METER_INSTANCE_ID_INVALID
+ /*
+ * This value indicates the destination MAC address in
+ * the Ethernet header.
+ */
+ uint8_t dst_macaddr[6];
+ /*
+ * This value indicates the VLAN ID of the outer VLAN tag
+ * in the Ethernet header.
+ */
+ uint16_t ovlan_vid;
+ /*
+ * This value indicates the VLAN ID of the inner VLAN tag
+ * in the Ethernet header.
+ */
+ uint16_t ivlan_vid;
+ /* This value indicates the ethertype in the Ethernet header. */
+ uint16_t ethertype;
+ /*
+ * This value indicates the type of IP address.
+ * 4 - IPv4
+ * 6 - IPv6
+ * All others are invalid.
+ */
+ uint8_t ip_addr_type;
+ /* invalid */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_UNKNOWN UINT32_C(0x0)
+ /* IPv4 */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV4 UINT32_C(0x4)
+ /* IPv6 */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV6 UINT32_C(0x6)
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_LAST \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV6
+ /*
+ * The value of protocol filed in IP header.
+ * Applies to UDP and TCP traffic.
+ * 6 - TCP
+ * 17 - UDP
+ */
+ uint8_t ip_protocol;
+ /* invalid */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_PROTOCOL_UNKNOWN UINT32_C(0x0)
+ /* TCP */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_PROTOCOL_TCP UINT32_C(0x6)
+ /* UDP */
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_PROTOCOL_UDP UINT32_C(0x11)
+ #define HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_PROTOCOL_LAST \
+ HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_PROTOCOL_UDP
+ uint8_t unused_1[2];
+ /*
+ * The value of source IP address to be used in filtering.
+ * For IPv4, first four bytes represent the IP address.
+ */
+ uint32_t src_ipaddr[4];
+ /*
+ * big_endian = True
+ * The value of destination IP address to be used in filtering.
+ * For IPv4, first four bytes represent the IP address.
+ */
+ uint32_t dst_ipaddr[4];
+ /*
+ * The value of source port to be used in filtering.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t src_port;
+ /*
+ * The value of destination port to be used in filtering.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t dst_port;
+ /*
+ * If set, this value shall represent the
+ * Logical VNIC ID of the destination VNIC for the RX
+ * path and network port id of the destination port for
+ * the TX path.
+ */
+ uint16_t dst_id;
+ /*
+ * Logical VNIC ID of the VNIC where traffic is
+ * mirrored.
+ */
+ uint16_t mirror_vnic_id;
+ /* Logical ID of the encapsulation record. */
+ uint32_t encap_record_id;
+ uint8_t unused_2[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_em_flow_alloc_output (size:192b/24B) */
+struct hwrm_cfa_em_flow_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This value is an opaque id into CFA data structures. */
+ uint64_t em_filter_id;
+ /*
+ * This is the ID of the flow associated with this
+ * filter.
+ * This value shall be used to match and associate the
+ * flow identifier returned in completion records.
+ * A value of 0xFFFFFFFF shall indicate no flow id.
+ */
+ uint32_t flow_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_cfa_em_flow_free *
+ *************************/
+
+
+/* hwrm_cfa_em_flow_free_input (size:192b/24B) */
+struct hwrm_cfa_em_flow_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* This value is an opaque id into CFA data structures. */
+ uint64_t em_filter_id;
+} __attribute__((packed));
+
+/* hwrm_cfa_em_flow_free_output (size:128b/16B) */
+struct hwrm_cfa_em_flow_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_em_flow_cfg *
+ ************************/
+
+
+/* hwrm_cfa_em_flow_cfg_input (size:384b/48B) */
+struct hwrm_cfa_em_flow_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the new_dst_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_CFG_INPUT_ENABLES_NEW_DST_ID \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the new_mirror_vnic_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the new_meter_instance_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_EM_FLOW_CFG_INPUT_ENABLES_NEW_METER_INSTANCE_ID \
+ UINT32_C(0x4)
+ uint8_t unused_0[4];
+ /* This value is an opaque id into CFA data structures. */
+ uint64_t em_filter_id;
+ /*
+ * If set, this value shall represent the new
+ * Logical VNIC ID of the destination VNIC for the RX
+ * path and network port id of the destination port for
+ * the TX path.
+ */
+ uint32_t new_dst_id;
+ /*
+ * New Logical VNIC ID of the VNIC where traffic is
+ * mirrored.
+ */
+ uint32_t new_mirror_vnic_id;
+ /*
+ * New meter to attach to the flow. Specifying the
+ * invalid instance ID is used to remove any existing
+ * meter from the flow.
+ */
+ uint16_t new_meter_instance_id;
+ /*
+ * A value of 0xfff is considered invalid and implies the
+ * instance is not configured.
+ */
+ #define HWRM_CFA_EM_FLOW_CFG_INPUT_NEW_METER_INSTANCE_ID_INVALID \
+ UINT32_C(0xffff)
+ #define HWRM_CFA_EM_FLOW_CFG_INPUT_NEW_METER_INSTANCE_ID_LAST \
+ HWRM_CFA_EM_FLOW_CFG_INPUT_NEW_METER_INSTANCE_ID_INVALID
+ uint8_t unused_1[6];
+} __attribute__((packed));
+
+/* hwrm_cfa_em_flow_cfg_output (size:128b/16B) */
+struct hwrm_cfa_em_flow_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_meter_profile_alloc *
+ ********************************/
+
+
+/* hwrm_cfa_meter_profile_alloc_input (size:320b/40B) */
+struct hwrm_cfa_meter_profile_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint8_t flags;
+ /*
+ * 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_CFA_METER_PROFILE_ALLOC_INPUT_FLAGS_PATH UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_FLAGS_PATH_TX \
+ UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_FLAGS_PATH_RX \
+ UINT32_C(0x1)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_FLAGS_PATH_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_INPUT_FLAGS_PATH_RX
+ /* The meter algorithm type. */
+ uint8_t meter_type;
+ /* RFC 2697 (srTCM) */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_METER_TYPE_RFC2697 \
+ UINT32_C(0x0)
+ /* RFC 2698 (trTCM) */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_METER_TYPE_RFC2698 \
+ UINT32_C(0x1)
+ /* RFC 4115 (trTCM) */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_METER_TYPE_RFC4115 \
+ UINT32_C(0x2)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_METER_TYPE_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_INPUT_METER_TYPE_RFC4115
+ /*
+ * This field is reserved for the future use.
+ * It shall be set to 0.
+ */
+ uint16_t reserved1;
+ /*
+ * This field is reserved for the future use.
+ * It shall be set to 0.
+ */
+ uint32_t reserved2;
+ /* A meter rate specified in bytes-per-second. */
+ uint32_t commit_rate;
+ /* The bandwidth value. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_SCALE_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_UNIT_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_RATE_BW_VALUE_UNIT_INVALID
+ /* A meter burst size specified in bytes. */
+ uint32_t commit_burst;
+ /* The bandwidth value. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_SCALE_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_UNIT_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_INPUT_COMMIT_BURST_BW_VALUE_UNIT_INVALID
+ /* A meter rate specified in bytes-per-second. */
+ uint32_t excess_peak_rate;
+ /* The bandwidth value. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_SCALE_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_INVALID
+ /* A meter burst size specified in bytes. */
+ uint32_t excess_peak_burst;
+ /* The bandwidth value. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_SCALE_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_INVALID
+} __attribute__((packed));
+
+/* hwrm_cfa_meter_profile_alloc_output (size:128b/16B) */
+struct hwrm_cfa_meter_profile_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This value identifies a meter profile in CFA. */
+ uint16_t meter_profile_id;
+ /*
+ * A value of 0xfff is considered invalid and implies the
+ * profile is not configured.
+ */
+ #define HWRM_CFA_METER_PROFILE_ALLOC_OUTPUT_METER_PROFILE_ID_INVALID \
+ UINT32_C(0xffff)
+ #define HWRM_CFA_METER_PROFILE_ALLOC_OUTPUT_METER_PROFILE_ID_LAST \
+ HWRM_CFA_METER_PROFILE_ALLOC_OUTPUT_METER_PROFILE_ID_INVALID
+ uint8_t unused_0[5];
+ /*
+ * 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_cfa_meter_profile_free *
+ *******************************/
+
+
+/* hwrm_cfa_meter_profile_free_input (size:192b/24B) */
+struct hwrm_cfa_meter_profile_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint8_t flags;
+ /*
+ * 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_CFA_METER_PROFILE_FREE_INPUT_FLAGS_PATH UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_CFA_METER_PROFILE_FREE_INPUT_FLAGS_PATH_TX \
+ UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_CFA_METER_PROFILE_FREE_INPUT_FLAGS_PATH_RX \
+ UINT32_C(0x1)
+ #define HWRM_CFA_METER_PROFILE_FREE_INPUT_FLAGS_PATH_LAST \
+ HWRM_CFA_METER_PROFILE_FREE_INPUT_FLAGS_PATH_RX
+ uint8_t unused_0;
+ /* This value identifies a meter profile in CFA. */
+ uint16_t meter_profile_id;
+ /*
+ * A value of 0xfff is considered invalid and implies the
+ * profile is not configured.
+ */
+ #define HWRM_CFA_METER_PROFILE_FREE_INPUT_METER_PROFILE_ID_INVALID \
+ UINT32_C(0xffff)
+ #define HWRM_CFA_METER_PROFILE_FREE_INPUT_METER_PROFILE_ID_LAST \
+ HWRM_CFA_METER_PROFILE_FREE_INPUT_METER_PROFILE_ID_INVALID
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_meter_profile_free_output (size:128b/16B) */
+struct hwrm_cfa_meter_profile_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_meter_profile_cfg *
+ ******************************/
+
+
+/* hwrm_cfa_meter_profile_cfg_input (size:320b/40B) */
+struct hwrm_cfa_meter_profile_cfg_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint8_t flags;
+ /*
+ * 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_CFA_METER_PROFILE_CFG_INPUT_FLAGS_PATH UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_FLAGS_PATH_TX UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_FLAGS_PATH_RX UINT32_C(0x1)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_FLAGS_PATH_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_FLAGS_PATH_RX
+ /* The meter algorithm type. */
+ uint8_t meter_type;
+ /* RFC 2697 (srTCM) */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_METER_TYPE_RFC2697 \
+ UINT32_C(0x0)
+ /* RFC 2698 (trTCM) */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_METER_TYPE_RFC2698 \
+ UINT32_C(0x1)
+ /* RFC 4115 (trTCM) */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_METER_TYPE_RFC4115 \
+ UINT32_C(0x2)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_METER_TYPE_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_METER_TYPE_RFC4115
+ /* This value identifies a meter profile in CFA. */
+ uint16_t meter_profile_id;
+ /*
+ * A value of 0xfff is considered invalid and implies the
+ * profile is not configured.
+ */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_METER_PROFILE_ID_INVALID \
+ UINT32_C(0xffff)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_METER_PROFILE_ID_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_METER_PROFILE_ID_INVALID
+ /*
+ * This field is reserved for the future use.
+ * It shall be set to 0.
+ */
+ uint32_t reserved;
+ /* A meter rate specified in bytes-per-second. */
+ uint32_t commit_rate;
+ /* The bandwidth value. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_SCALE_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_UNIT_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_RATE_BW_VALUE_UNIT_INVALID
+ /* A meter burst size specified in bytes. */
+ uint32_t commit_burst;
+ /* The bandwidth value. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_SCALE_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_UNIT_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_COMMIT_BURST_BW_VALUE_UNIT_INVALID
+ /* A meter rate specified in bytes-per-second. */
+ uint32_t excess_peak_rate;
+ /* The bandwidth value. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_SCALE_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_RATE_BW_VALUE_UNIT_INVALID
+ /* A meter burst size specified in bytes. */
+ uint32_t excess_peak_burst;
+ /* The bandwidth value. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_MASK \
+ UINT32_C(0xfffffff)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_SFT \
+ 0
+ /* The granularity of the value (bits or bytes). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_SCALE \
+ UINT32_C(0x10000000)
+ /* Value is in bits. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_SCALE_BITS \
+ (UINT32_C(0x0) << 28)
+ /* Value is in bytes. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_SCALE_BYTES \
+ (UINT32_C(0x1) << 28)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_SCALE_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_SCALE_BYTES
+ /* bw_value_unit is 3 b */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_MASK \
+ UINT32_C(0xe0000000)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_SFT \
+ 29
+ /* Value is in Mb or MB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_MEGA \
+ (UINT32_C(0x0) << 29)
+ /* Value is in Kb or KB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_KILO \
+ (UINT32_C(0x2) << 29)
+ /* Value is in bits or bytes. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_BASE \
+ (UINT32_C(0x4) << 29)
+ /* Value is in Gb or GB (base 10). */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_GIGA \
+ (UINT32_C(0x6) << 29)
+ /* Value is in 1/100th of a percentage of total bandwidth. */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_PERCENT1_100 \
+ (UINT32_C(0x1) << 29)
+ /* Invalid unit */
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_INVALID \
+ (UINT32_C(0x7) << 29)
+ #define HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_LAST \
+ HWRM_CFA_METER_PROFILE_CFG_INPUT_EXCESS_PEAK_BURST_BW_VALUE_UNIT_INVALID
+} __attribute__((packed));
+
+/* hwrm_cfa_meter_profile_cfg_output (size:128b/16B) */
+struct hwrm_cfa_meter_profile_cfg_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_meter_instance_alloc *
+ *********************************/
+
+
+/* hwrm_cfa_meter_instance_alloc_input (size:192b/24B) */
+struct hwrm_cfa_meter_instance_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint8_t flags;
+ /*
+ * 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_CFA_METER_INSTANCE_ALLOC_INPUT_FLAGS_PATH \
+ UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_CFA_METER_INSTANCE_ALLOC_INPUT_FLAGS_PATH_TX \
+ UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_CFA_METER_INSTANCE_ALLOC_INPUT_FLAGS_PATH_RX \
+ UINT32_C(0x1)
+ #define HWRM_CFA_METER_INSTANCE_ALLOC_INPUT_FLAGS_PATH_LAST \
+ HWRM_CFA_METER_INSTANCE_ALLOC_INPUT_FLAGS_PATH_RX
+ uint8_t unused_0;
+ /* This value identifies a meter profile in CFA. */
+ uint16_t meter_profile_id;
+ /*
+ * A value of 0xfff is considered invalid and implies the
+ * profile is not configured.
+ */
+ #define HWRM_CFA_METER_INSTANCE_ALLOC_INPUT_METER_PROFILE_ID_INVALID \
+ UINT32_C(0xffff)
+ #define HWRM_CFA_METER_INSTANCE_ALLOC_INPUT_METER_PROFILE_ID_LAST \
+ HWRM_CFA_METER_INSTANCE_ALLOC_INPUT_METER_PROFILE_ID_INVALID
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_meter_instance_alloc_output (size:128b/16B) */
+struct hwrm_cfa_meter_instance_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This value identifies a meter instance in CFA. */
+ uint16_t meter_instance_id;
+ /*
+ * A value of 0xfff is considered invalid and implies the
+ * instance is not configured.
+ */
+ #define HWRM_CFA_METER_INSTANCE_ALLOC_OUTPUT_METER_INSTANCE_ID_INVALID \
+ UINT32_C(0xffff)
+ #define HWRM_CFA_METER_INSTANCE_ALLOC_OUTPUT_METER_INSTANCE_ID_LAST \
+ HWRM_CFA_METER_INSTANCE_ALLOC_OUTPUT_METER_INSTANCE_ID_INVALID
+ uint8_t unused_0[5];
+ /*
+ * 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_cfa_meter_instance_free *
+ ********************************/
+
+
+/* hwrm_cfa_meter_instance_free_input (size:192b/24B) */
+struct hwrm_cfa_meter_instance_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint8_t flags;
+ /*
+ * 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_CFA_METER_INSTANCE_FREE_INPUT_FLAGS_PATH UINT32_C(0x1)
+ /* tx path */
+ #define HWRM_CFA_METER_INSTANCE_FREE_INPUT_FLAGS_PATH_TX \
+ UINT32_C(0x0)
+ /* rx path */
+ #define HWRM_CFA_METER_INSTANCE_FREE_INPUT_FLAGS_PATH_RX \
+ UINT32_C(0x1)
+ #define HWRM_CFA_METER_INSTANCE_FREE_INPUT_FLAGS_PATH_LAST \
+ HWRM_CFA_METER_INSTANCE_FREE_INPUT_FLAGS_PATH_RX
+ uint8_t unused_0;
+ /* This value identifies a meter instance in CFA. */
+ uint16_t meter_instance_id;
+ /*
+ * A value of 0xfff is considered invalid and implies the
+ * instance is not configured.
+ */
+ #define HWRM_CFA_METER_INSTANCE_FREE_INPUT_METER_INSTANCE_ID_INVALID \
+ UINT32_C(0xffff)
+ #define HWRM_CFA_METER_INSTANCE_FREE_INPUT_METER_INSTANCE_ID_LAST \
+ HWRM_CFA_METER_INSTANCE_FREE_INPUT_METER_INSTANCE_ID_INVALID
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_meter_instance_free_output (size:128b/16B) */
+struct hwrm_cfa_meter_instance_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_decap_filter_alloc *
+ *******************************/
+
+
+/* hwrm_cfa_decap_filter_alloc_input (size:832b/104B) */
+struct hwrm_cfa_decap_filter_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /* ovs_tunnel is 1 b */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_FLAGS_OVS_TUNNEL \
+ UINT32_C(0x1)
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the tunnel_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE \
+ UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the tunnel_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_ID \
+ UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the src_macaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_SRC_MACADDR \
+ UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the dst_macaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_DST_MACADDR \
+ UINT32_C(0x8)
+ /*
+ * This bit must be '1' for the ovlan_vid field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_OVLAN_VID \
+ UINT32_C(0x10)
+ /*
+ * This bit must be '1' for the ivlan_vid field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_IVLAN_VID \
+ UINT32_C(0x20)
+ /*
+ * This bit must be '1' for the t_ovlan_vid field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_T_OVLAN_VID \
+ UINT32_C(0x40)
+ /*
+ * This bit must be '1' for the t_ivlan_vid field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_T_IVLAN_VID \
+ UINT32_C(0x80)
+ /*
+ * This bit must be '1' for the ethertype field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_ETHERTYPE \
+ UINT32_C(0x100)
+ /*
+ * This bit must be '1' for the src_ipaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_SRC_IPADDR \
+ UINT32_C(0x200)
+ /*
+ * This bit must be '1' for the dst_ipaddr field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_DST_IPADDR \
+ UINT32_C(0x400)
+ /*
+ * This bit must be '1' for the ipaddr_type field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_IPADDR_TYPE \
+ UINT32_C(0x800)
+ /*
+ * This bit must be '1' for the ip_protocol field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_IP_PROTOCOL \
+ UINT32_C(0x1000)
+ /*
+ * This bit must be '1' for the src_port field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_SRC_PORT \
+ UINT32_C(0x2000)
+ /*
+ * This bit must be '1' for the dst_port field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_DST_PORT \
+ UINT32_C(0x4000)
+ /*
+ * This bit must be '1' for the dst_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_DST_ID \
+ UINT32_C(0x8000)
+ /*
+ * This bit must be '1' for the mirror_vnic_id field to be
+ * configured.
+ */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID \
+ UINT32_C(0x10000)
+ /*
+ * Tunnel identifier.
+ * Virtual Network Identifier (VNI). Only valid with
+ * tunnel_types VXLAN, NVGRE, and Geneve.
+ * Only lower 24-bits of VNI field are used
+ * in setting up the filter.
+ */
+ uint32_t tunnel_id;
+ /* Tunnel Type. */
+ uint8_t tunnel_type;
+ /* Non-tunnel */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+ UINT32_C(0x0)
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Network Virtualization Generic Routing Encapsulation (NVGRE) */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+ UINT32_C(0x2)
+ /* Generic Routing Encapsulation (GRE) inside Ethernet payload */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE \
+ UINT32_C(0x3)
+ /* IP in IP */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP \
+ UINT32_C(0x4)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* Multi-Protocol Lable Switching (MPLS) */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS \
+ UINT32_C(0x6)
+ /* Stateless Transport Tunnel (STT) */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT \
+ UINT32_C(0x7)
+ /* Generic Routing Encapsulation (GRE) inside IP datagram payload */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE \
+ UINT32_C(0x8)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Any tunneled traffic */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+ UINT32_C(0xff)
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL
+ uint8_t unused_0;
+ uint16_t unused_1;
+ /*
+ * This value indicates the source MAC address in
+ * the Ethernet header.
+ */
+ uint8_t src_macaddr[6];
+ uint8_t unused_2[2];
+ /*
+ * This value indicates the destination MAC address in
+ * the Ethernet header.
+ */
+ uint8_t dst_macaddr[6];
+ /*
+ * This value indicates the VLAN ID of the outer VLAN tag
+ * in the Ethernet header.
+ */
+ uint16_t ovlan_vid;
+ /*
+ * This value indicates the VLAN ID of the inner VLAN tag
+ * in the Ethernet header.
+ */
+ uint16_t ivlan_vid;
+ /*
+ * This value indicates the VLAN ID of the outer VLAN tag
+ * in the tunnel Ethernet header.
+ */
+ uint16_t t_ovlan_vid;
+ /*
+ * This value indicates the VLAN ID of the inner VLAN tag
+ * in the tunnel Ethernet header.
+ */
+ uint16_t t_ivlan_vid;
+ /* This value indicates the ethertype in the Ethernet header. */
+ uint16_t ethertype;
+ /*
+ * This value indicates the type of IP address.
+ * 4 - IPv4
+ * 6 - IPv6
+ * All others are invalid.
+ */
+ uint8_t ip_addr_type;
+ /* invalid */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_UNKNOWN \
+ UINT32_C(0x0)
+ /* IPv4 */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV4 \
+ UINT32_C(0x4)
+ /* IPv6 */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV6 \
+ UINT32_C(0x6)
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_LAST \
+ HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV6
+ /*
+ * The value of protocol filed in IP header.
+ * Applies to UDP and TCP traffic.
+ * 6 - TCP
+ * 17 - UDP
+ */
+ uint8_t ip_protocol;
+ /* invalid */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_IP_PROTOCOL_UNKNOWN \
+ UINT32_C(0x0)
+ /* TCP */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_IP_PROTOCOL_TCP \
+ UINT32_C(0x6)
+ /* UDP */
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_IP_PROTOCOL_UDP \
+ UINT32_C(0x11)
+ #define HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_IP_PROTOCOL_LAST \
+ HWRM_CFA_DECAP_FILTER_ALLOC_INPUT_IP_PROTOCOL_UDP
+ uint16_t unused_3;
+ uint32_t unused_4;
+ /*
+ * The value of source IP address to be used in filtering.
+ * For IPv4, first four bytes represent the IP address.
+ */
+ uint32_t src_ipaddr[4];
+ /*
+ * The value of destination IP address to be used in filtering.
+ * For IPv4, first four bytes represent the IP address.
+ */
+ uint32_t dst_ipaddr[4];
+ /*
+ * The value of source port to be used in filtering.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t src_port;
+ /*
+ * The value of destination port to be used in filtering.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t dst_port;
+ /*
+ * If set, this value shall represent the
+ * Logical VNIC ID of the destination VNIC for the RX
+ * path.
+ */
+ uint16_t dst_id;
+ /*
+ * If set, this value shall represent the L2 context that matches the L2
+ * information of the decap filter.
+ */
+ uint16_t l2_ctxt_ref_id;
+} __attribute__((packed));
+
+/* hwrm_cfa_decap_filter_alloc_output (size:128b/16B) */
+struct hwrm_cfa_decap_filter_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This value is an opaque id into CFA data structures. */
+ uint32_t decap_filter_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_cfa_decap_filter_free *
+ ******************************/
+
+
+/* hwrm_cfa_decap_filter_free_input (size:192b/24B) */
+struct hwrm_cfa_decap_filter_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* This value is an opaque id into CFA data structures. */
+ uint32_t decap_filter_id;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_decap_filter_free_output (size:128b/16B) */
+struct hwrm_cfa_decap_filter_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_flow_alloc *
+ ***********************/
+
+
+/* hwrm_cfa_flow_alloc_input (size:1024b/128B) */
+struct hwrm_cfa_flow_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint16_t flags;
+ /* tunnel is 1 b */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_TUNNEL UINT32_C(0x1)
+ /* num_vlan is 2 b */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_NUM_VLAN_MASK UINT32_C(0x6)
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_NUM_VLAN_SFT 1
+ /* no tags */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_NUM_VLAN_NONE \
+ (UINT32_C(0x0) << 1)
+ /* 1 tag */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_NUM_VLAN_ONE \
+ (UINT32_C(0x1) << 1)
+ /* 2 tags */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_NUM_VLAN_TWO \
+ (UINT32_C(0x2) << 1)
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_NUM_VLAN_LAST \
+ HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_NUM_VLAN_TWO
+ /* Enumeration denoting the Flow Type. */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_FLOWTYPE_MASK UINT32_C(0x38)
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_FLOWTYPE_SFT 3
+ /* L2 flow */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_FLOWTYPE_L2 \
+ (UINT32_C(0x0) << 3)
+ /* IPV4 flow */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_FLOWTYPE_IPV4 \
+ (UINT32_C(0x1) << 3)
+ /* IPV6 flow */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_FLOWTYPE_IPV6 \
+ (UINT32_C(0x2) << 3)
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_FLOWTYPE_LAST \
+ HWRM_CFA_FLOW_ALLOC_INPUT_FLAGS_FLOWTYPE_IPV6
+ /*
+ * Tx Flow: vf fid.
+ * Rx Flow: pf fid.
+ */
+ uint16_t src_fid;
+ /* Tunnel handle valid when tunnel flag is set. */
+ uint32_t tunnel_handle;
+ uint16_t action_flags;
+ /*
+ * Setting of this flag indicates drop action. If this flag is not set,
+ * then it should be considered accept action.
+ */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_ACTION_FLAGS_FWD \
+ UINT32_C(0x1)
+ /* recycle is 1 b */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_ACTION_FLAGS_RECYCLE \
+ UINT32_C(0x2)
+ /*
+ * Setting of this flag indicates drop action. If this flag is not set,
+ * then it should be considered accept action.
+ */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_ACTION_FLAGS_DROP \
+ UINT32_C(0x4)
+ /* meter is 1 b */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_ACTION_FLAGS_METER \
+ UINT32_C(0x8)
+ /* tunnel is 1 b */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_ACTION_FLAGS_TUNNEL \
+ UINT32_C(0x10)
+ /* nat_src is 1 b */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_ACTION_FLAGS_NAT_SRC \
+ UINT32_C(0x20)
+ /* nat_dest is 1 b */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_ACTION_FLAGS_NAT_DEST \
+ UINT32_C(0x40)
+ /* nat_ipv4_address is 1 b */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_ACTION_FLAGS_NAT_IPV4_ADDRESS \
+ UINT32_C(0x80)
+ /* l2_header_rewrite is 1 b */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_ACTION_FLAGS_L2_HEADER_REWRITE \
+ UINT32_C(0x100)
+ /* ttl_decrement is 1 b */
+ #define HWRM_CFA_FLOW_ALLOC_INPUT_ACTION_FLAGS_TTL_DECREMENT \
+ UINT32_C(0x200)
+ /*
+ * Tx Flow: pf or vf fid.
+ * Rx Flow: vf fid.
+ */
+ uint16_t dst_fid;
+ /* VLAN tpid, valid when push_vlan flag is set. */
+ uint16_t l2_rewrite_vlan_tpid;
+ /* VLAN tci, valid when push_vlan flag is set. */
+ uint16_t l2_rewrite_vlan_tci;
+ /* Meter id, valid when meter flag is set. */
+ uint16_t act_meter_id;
+ /* Flow with the same l2 context tcam key. */
+ uint16_t ref_flow_handle;
+ /* This value sets the match value for the ethertype. */
+ uint16_t ethertype;
+ /* valid when num tags is 1 or 2. */
+ uint16_t outer_vlan_tci;
+ /* This value sets the match value for the Destination MAC address. */
+ uint16_t dmac[3];
+ /* valid when num tags is 2. */
+ uint16_t inner_vlan_tci;
+ /* This value sets the match value for the Source MAC address. */
+ uint16_t smac[3];
+ /* The bit length of destination IP address mask. */
+ uint8_t ip_dst_mask_len;
+ /* The bit length of source IP address mask. */
+ uint8_t ip_src_mask_len;
+ /* The value of destination IPv4/IPv6 address. */
+ uint32_t ip_dst[4];
+ /* The source IPv4/IPv6 address. */
+ uint32_t ip_src[4];
+ /*
+ * The value of source port.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t l4_src_port;
+ /*
+ * The value of source port mask.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t l4_src_port_mask;
+ /*
+ * The value of destination port.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t l4_dst_port;
+ /*
+ * The value of destination port mask.
+ * Applies to UDP and TCP traffic.
+ */
+ uint16_t l4_dst_port_mask;
+ /*
+ * NAT IPv4/6 address based on address type flag.
+ * 0 values are ignored.
+ */
+ uint32_t nat_ip_address[4];
+ /* L2 header re-write Destination MAC address. */
+ uint16_t l2_rewrite_dmac[3];
+ /*
+ * The NAT source/destination port based on direction flag.
+ * Applies to UDP and TCP traffic.
+ * 0 values are ignored.
+ */
+ uint16_t nat_port;
+ /* L2 header re-write Source MAC address. */
+ uint16_t l2_rewrite_smac[3];
+ /* The value of ip protocol. */
+ uint8_t ip_proto;
+ uint8_t unused_0;
+} __attribute__((packed));
+
+/* hwrm_cfa_flow_alloc_output (size:128b/16B) */
+struct hwrm_cfa_flow_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Flow record index. */
+ uint16_t flow_handle;
+ uint8_t unused_0[5];
+ /*
+ * 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_cfa_flow_free *
+ **********************/
+
+
+/* hwrm_cfa_flow_free_input (size:192b/24B) */
+struct hwrm_cfa_flow_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Flow record index. */
+ uint16_t flow_handle;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_cfa_flow_free_output (size:256b/32B) */
+struct hwrm_cfa_flow_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* packet is 64 b */
+ uint64_t packet;
+ /* byte is 64 b */
+ uint64_t byte;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_flow_info *
+ **********************/
+
+
+/* hwrm_cfa_flow_info_input (size:192b/24B) */
+struct hwrm_cfa_flow_info_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Flow record index. */
+ uint16_t flow_handle;
+ /* Max flow handle */
+ #define HWRM_CFA_FLOW_INFO_INPUT_FLOW_HANDLE_MAX_MASK \
+ UINT32_C(0xfff)
+ #define HWRM_CFA_FLOW_INFO_INPUT_FLOW_HANDLE_MAX_SFT 0
+ /* CNP flow handle */
+ #define HWRM_CFA_FLOW_INFO_INPUT_FLOW_HANDLE_CNP_CNT \
+ UINT32_C(0x1000)
+ /* Direction rx = 1 */
+ #define HWRM_CFA_FLOW_INFO_INPUT_FLOW_HANDLE_DIR_RX \
+ UINT32_C(0x8000)
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_cfa_flow_info_output (size:448b/56B) */
+struct hwrm_cfa_flow_info_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* flags is 8 b */
+ uint8_t flags;
+ /* profile is 8 b */
+ uint8_t profile;
+ /* src_fid is 16 b */
+ uint16_t src_fid;
+ /* dst_fid is 16 b */
+ uint16_t dst_fid;
+ /* l2_ctxt_id is 16 b */
+ uint16_t l2_ctxt_id;
+ /* em_info is 64 b */
+ uint64_t em_info;
+ /* tcam_info is 64 b */
+ uint64_t tcam_info;
+ /* vfp_tcam_info is 64 b */
+ uint64_t vfp_tcam_info;
+ /* ar_id is 16 b */
+ uint16_t ar_id;
+ /* flow_handle is 16 b */
+ uint16_t flow_handle;
+ /* tunnel_handle is 32 b */
+ uint32_t tunnel_handle;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_flow_flush *
+ ***********************/
+
+
+/* hwrm_cfa_flow_flush_input (size:192b/24B) */
+struct hwrm_cfa_flow_flush_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_flow_flush_output (size:128b/16B) */
+struct hwrm_cfa_flow_flush_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_flow_stats *
+ ***********************/
+
+
+/* hwrm_cfa_flow_stats_input (size:320b/40B) */
+struct hwrm_cfa_flow_stats_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Flow handle. */
+ uint16_t num_flows;
+ /* Flow handle. */
+ uint16_t flow_handle_0;
+ /* Flow handle. */
+ uint16_t flow_handle_1;
+ /* Flow handle. */
+ uint16_t flow_handle_2;
+ /* Flow handle. */
+ uint16_t flow_handle_3;
+ /* Flow handle. */
+ uint16_t flow_handle_4;
+ /* Flow handle. */
+ uint16_t flow_handle_5;
+ /* Flow handle. */
+ uint16_t flow_handle_6;
+ /* Flow handle. */
+ uint16_t flow_handle_7;
+ /* Flow handle. */
+ uint16_t flow_handle_8;
+ /* Flow handle. */
+ uint16_t flow_handle_9;
+ uint8_t unused_0[2];
+} __attribute__((packed));
+
+/* hwrm_cfa_flow_stats_output (size:1408b/176B) */
+struct hwrm_cfa_flow_stats_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* packet_0 is 64 b */
+ uint64_t packet_0;
+ /* packet_1 is 64 b */
+ uint64_t packet_1;
+ /* packet_2 is 64 b */
+ uint64_t packet_2;
+ /* packet_3 is 64 b */
+ uint64_t packet_3;
+ /* packet_4 is 64 b */
+ uint64_t packet_4;
+ /* packet_5 is 64 b */
+ uint64_t packet_5;
+ /* packet_6 is 64 b */
+ uint64_t packet_6;
+ /* packet_7 is 64 b */
+ uint64_t packet_7;
+ /* packet_8 is 64 b */
+ uint64_t packet_8;
+ /* packet_9 is 64 b */
+ uint64_t packet_9;
+ /* byte_0 is 64 b */
+ uint64_t byte_0;
+ /* byte_1 is 64 b */
+ uint64_t byte_1;
+ /* byte_2 is 64 b */
+ uint64_t byte_2;
+ /* byte_3 is 64 b */
+ uint64_t byte_3;
+ /* byte_4 is 64 b */
+ uint64_t byte_4;
+ /* byte_5 is 64 b */
+ uint64_t byte_5;
+ /* byte_6 is 64 b */
+ uint64_t byte_6;
+ /* byte_7 is 64 b */
+ uint64_t byte_7;
+ /* byte_8 is 64 b */
+ uint64_t byte_8;
+ /* byte_9 is 64 b */
+ uint64_t byte_9;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_vf_pair_alloc *
+ **************************/
+
+
+/* hwrm_cfa_vf_pair_alloc_input (size:448b/56B) */
+struct hwrm_cfa_vf_pair_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Logical VF number (range: 0 -> MAX_VFS -1). */
+ uint16_t vf_a_id;
+ /* Logical VF number (range: 0 -> MAX_VFS -1). */
+ uint16_t vf_b_id;
+ uint8_t unused_0[4];
+ /* VF Pair name (32 byte string). */
+ char pair_name[32];
+} __attribute__((packed));
+
+/* hwrm_cfa_vf_pair_alloc_output (size:128b/16B) */
+struct hwrm_cfa_vf_pair_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_vf_pair_free *
+ *************************/
+
+
+/* hwrm_cfa_vf_pair_free_input (size:384b/48B) */
+struct hwrm_cfa_vf_pair_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* VF Pair name (32 byte string). */
+ char pair_name[32];
+} __attribute__((packed));
+
+/* hwrm_cfa_vf_pair_free_output (size:128b/16B) */
+struct hwrm_cfa_vf_pair_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_vf_pair_info *
+ *************************/
+
+
+/* hwrm_cfa_vf_pair_info_input (size:448b/56B) */
+struct hwrm_cfa_vf_pair_info_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /* If this flag is set, lookup by name else lookup by index. */
+ #define HWRM_CFA_VF_PAIR_INFO_INPUT_FLAGS_LOOKUP_TYPE UINT32_C(0x1)
+ /* vf pair table index. */
+ uint16_t vf_pair_index;
+ uint8_t unused_0[2];
+ /* VF Pair name (32 byte string). */
+ char vf_pair_name[32];
+} __attribute__((packed));
+
+/* hwrm_cfa_vf_pair_info_output (size:512b/64B) */
+struct hwrm_cfa_vf_pair_info_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* vf pair table index. */
+ uint16_t next_vf_pair_index;
+ /* vf pair member a's vf_fid. */
+ uint16_t vf_a_fid;
+ /* vf pair member a's Linux logical VF number. */
+ uint16_t vf_a_index;
+ /* vf pair member b's vf_fid. */
+ uint16_t vf_b_fid;
+ /* vf pair member a's Linux logical VF number. */
+ uint16_t vf_b_index;
+ /* vf pair state. */
+ uint8_t pair_state;
+ /* Pair has been allocated */
+ #define HWRM_CFA_VF_PAIR_INFO_OUTPUT_PAIR_STATE_ALLOCATED UINT32_C(0x1)
+ /* Both pair members are active */
+ #define HWRM_CFA_VF_PAIR_INFO_OUTPUT_PAIR_STATE_ACTIVE UINT32_C(0x2)
+ #define HWRM_CFA_VF_PAIR_INFO_OUTPUT_PAIR_STATE_LAST \
+ HWRM_CFA_VF_PAIR_INFO_OUTPUT_PAIR_STATE_ACTIVE
+ uint8_t unused_0[5];
+ /* VF Pair name (32 byte string). */
+ char pair_name[32];
+ uint8_t unused_1[7];
+ /*
+ * 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_cfa_pair_alloc *
+ ***********************/
+
+
+/* hwrm_cfa_pair_alloc_input (size:576b/72B) */
+struct hwrm_cfa_pair_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Pair mode (0-vf2fn, 1-rep2fn, 2-rep2rep, 3-proxy, 4-pfpair, 5-rep2fn_mod). */
+ uint8_t pair_mode;
+ /* Pair between VF on local host with PF or VF on specified host. */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_PAIR_MODE_VF2FN UINT32_C(0x0)
+ /* Pair between REP on local host with PF or VF on specified host. */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_PAIR_MODE_REP2FN UINT32_C(0x1)
+ /* Pair between REP on local host with REP on specified host. */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_PAIR_MODE_REP2REP UINT32_C(0x2)
+ /* Pair for the proxy interface. */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_PAIR_MODE_PROXY UINT32_C(0x3)
+ /* Pair for the PF interface. */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_PAIR_MODE_PFPAIR UINT32_C(0x4)
+ /* Modify exiting rep2fn pair and move pair to new PF. */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_PAIR_MODE_REP2FN_MOD UINT32_C(0x5)
+ /* Modify exiting rep2fn pairs paired with same PF and move pairs to new PF. */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_PAIR_MODE_REP2FN_MODALL UINT32_C(0x6)
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_PAIR_MODE_LAST \
+ HWRM_CFA_PAIR_ALLOC_INPUT_PAIR_MODE_REP2FN_MODALL
+ uint8_t unused_0;
+ /* Logical VF number (range: 0 -> MAX_VFS -1). */
+ uint16_t vf_a_id;
+ /* Logical Host (0xff-local host). */
+ uint8_t host_b_id;
+ /* Logical PF (0xff-PF for command channel). */
+ uint8_t pf_b_id;
+ /* Logical VF number (range: 0 -> MAX_VFS -1). */
+ uint16_t vf_b_id;
+ /* Loopback port (0xff-internal loopback), valid for mode-3. */
+ uint8_t port_id;
+ /* Priority used for encap of loopback packets valid for mode-3. */
+ uint8_t pri;
+ /* New PF for rep2fn modify, valid for mode 5. */
+ uint16_t new_pf_fid;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the q_ab field to be
+ * configured.
+ */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_ENABLES_Q_AB_VALID UINT32_C(0x1)
+ /*
+ * This bit must be '1' for the q_ba field to be
+ * configured.
+ */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_ENABLES_Q_BA_VALID UINT32_C(0x2)
+ /*
+ * This bit must be '1' for the fc_ab field to be
+ * configured.
+ */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_ENABLES_FC_AB_VALID UINT32_C(0x4)
+ /*
+ * This bit must be '1' for the fc_ba field to be
+ * configured.
+ */
+ #define HWRM_CFA_PAIR_ALLOC_INPUT_ENABLES_FC_BA_VALID UINT32_C(0x8)
+ /* VF Pair name (32 byte string). */
+ char pair_name[32];
+ /*
+ * The q_ab value specifies the logical index of the TX/RX CoS
+ * queue to be assigned for traffic in the A to B direction of
+ * the interface pair. The default value is 0.
+ */
+ uint8_t q_ab;
+ /*
+ * The q_ba value specifies the logical index of the TX/RX CoS
+ * queue to be assigned for traffic in the B to A direction of
+ * the interface pair. The default value is 1.
+ */
+ uint8_t q_ba;
+ /*
+ * Specifies whether RX ring flow control is disabled (0) or enabled
+ * (1) in the A to B direction. The default value is 0, meaning that
+ * packets will be dropped when the B-side RX rings are full.
+ */
+ uint8_t fc_ab;
+ /*
+ * Specifies whether RX ring flow control is disabled (0) or enabled
+ * (1) in the B to A direction. The default value is 1, meaning that
+ * the RX CoS queue will be flow controlled when the A-side RX rings
+ * are full.
+ */
+ uint8_t fc_ba;
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_pair_alloc_output (size:192b/24B) */
+struct hwrm_cfa_pair_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Only valid for modes 1 and 2. */
+ uint16_t rx_cfa_code_a;
+ /* Only valid for modes 1 and 2. */
+ uint16_t tx_cfa_action_a;
+ /* Only valid for mode 2. */
+ uint16_t rx_cfa_code_b;
+ /* Only valid for mode 2. */
+ uint16_t tx_cfa_action_b;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_pair_free *
+ **********************/
+
+
+/* hwrm_cfa_pair_free_input (size:384b/48B) */
+struct hwrm_cfa_pair_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* VF Pair name (32 byte string). */
+ char pair_name[32];
+} __attribute__((packed));
+
+/* hwrm_cfa_pair_free_output (size:128b/16B) */
+struct hwrm_cfa_pair_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_pair_info *
+ **********************/
+
+
+/* hwrm_cfa_pair_info_input (size:448b/56B) */
+struct hwrm_cfa_pair_info_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t flags;
+ /* If this flag is set, lookup by name else lookup by index. */
+ #define HWRM_CFA_PAIR_INFO_INPUT_FLAGS_LOOKUP_TYPE UINT32_C(0x1)
+ /* If this flag is set, lookup by PF id and VF id. */
+ #define HWRM_CFA_PAIR_INFO_INPUT_FLAGS_LOOKUP_REPRE UINT32_C(0x2)
+ /* Pair table index. */
+ uint16_t pair_index;
+ /* Pair pf index. */
+ uint8_t pair_pfid;
+ /* Pair vf index. */
+ uint8_t pair_vfid;
+ /* Pair name (32 byte string). */
+ char pair_name[32];
+} __attribute__((packed));
+
+/* hwrm_cfa_pair_info_output (size:576b/72B) */
+struct hwrm_cfa_pair_info_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Pair table index. */
+ uint16_t next_pair_index;
+ /* Pair member a's fid. */
+ uint16_t a_fid;
+ /* Logical host number. */
+ uint8_t host_a_index;
+ /* Logical PF number. */
+ uint8_t pf_a_index;
+ /* Pair member a's Linux logical VF number. */
+ uint16_t vf_a_index;
+ /* Rx CFA code. */
+ uint16_t rx_cfa_code_a;
+ /* Tx CFA action. */
+ uint16_t tx_cfa_action_a;
+ /* Pair member b's fid. */
+ uint16_t b_fid;
+ /* Logical host number. */
+ uint8_t host_b_index;
+ /* Logical PF number. */
+ uint8_t pf_b_index;
+ /* Pair member a's Linux logical VF number. */
+ uint16_t vf_b_index;
+ /* Rx CFA code. */
+ uint16_t rx_cfa_code_b;
+ /* Tx CFA action. */
+ uint16_t tx_cfa_action_b;
+ /* Pair mode (0-vf2fn, 1-rep2fn, 2-rep2rep, 3-proxy, 4-pfpair). */
+ uint8_t pair_mode;
+ /* Pair between VF on local host with PF or VF on specified host. */
+ #define HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_MODE_VF2FN UINT32_C(0x0)
+ /* Pair between REP on local host with PF or VF on specified host. */
+ #define HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_MODE_REP2FN UINT32_C(0x1)
+ /* Pair between REP on local host with REP on specified host. */
+ #define HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_MODE_REP2REP UINT32_C(0x2)
+ /* Pair for the proxy interface. */
+ #define HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_MODE_PROXY UINT32_C(0x3)
+ /* Pair for the PF interface. */
+ #define HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_MODE_PFPAIR UINT32_C(0x4)
+ #define HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_MODE_LAST \
+ HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_MODE_PFPAIR
+ /* Pair state. */
+ uint8_t pair_state;
+ /* Pair has been allocated */
+ #define HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_STATE_ALLOCATED UINT32_C(0x1)
+ /* Both pair members are active */
+ #define HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_STATE_ACTIVE UINT32_C(0x2)
+ #define HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_STATE_LAST \
+ HWRM_CFA_PAIR_INFO_OUTPUT_PAIR_STATE_ACTIVE
+ /* Pair name (32 byte string). */
+ char pair_name[32];
+ uint8_t unused_0[7];
+ /*
+ * 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_cfa_vfr_alloc *
+ **********************/
+
+
+/* hwrm_cfa_vfr_alloc_input (size:448b/56B) */
+struct hwrm_cfa_vfr_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Logical VF number (range: 0 -> MAX_VFS -1). */
+ uint16_t vf_id;
+ /*
+ * This field is reserved for the future use.
+ * It shall be set to 0.
+ */
+ uint16_t reserved;
+ uint8_t unused_0[4];
+ /* VF Representor name (32 byte string). */
+ char vfr_name[32];
+} __attribute__((packed));
+
+/* hwrm_cfa_vfr_alloc_output (size:128b/16B) */
+struct hwrm_cfa_vfr_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Rx CFA code. */
+ uint16_t rx_cfa_code;
+ /* Tx CFA action. */
+ uint16_t tx_cfa_action;
+ uint8_t unused_0[3];
+ /*
+ * 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_cfa_vfr_free *
+ *********************/
+
+
+/* hwrm_cfa_vfr_free_input (size:384b/48B) */
+struct hwrm_cfa_vfr_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* VF Representor name (32 byte string). */
+ char vfr_name[32];
+} __attribute__((packed));
+
+/* hwrm_cfa_vfr_free_output (size:128b/16B) */
+struct hwrm_cfa_vfr_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_tunnel_dst_port_query *
+ ******************************/
+
+
+/* hwrm_tunnel_dst_port_query_input (size:192b/24B) */
+struct hwrm_tunnel_dst_port_query_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Tunnel Type. */
+ uint8_t tunnel_type;
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Enhance Generic Routing Encapsulation (GRE version 1) inside IP datagram payload */
+ #define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_IPGRE_V1 \
+ UINT32_C(0xa)
+ #define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_IPGRE_V1
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/* hwrm_tunnel_dst_port_query_output (size:128b/16B) */
+struct hwrm_tunnel_dst_port_query_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * This field represents the identifier of L4 destination port
+ * used for the given tunnel type. This field is valid for
+ * specific tunnel types that use layer 4 (e.g. UDP)
+ * transports for tunneling.
+ */
+ uint16_t tunnel_dst_port_id;
+ /*
+ * This field represents the value of L4 destination port
+ * identified by tunnel_dst_port_id. This field is valid for
+ * specific tunnel types that use layer 4 (e.g. UDP)
+ * transports for tunneling.
+ * This field is in network byte order.
+ *
+ * A value of 0 means that the destination port is not
+ * configured.
+ */
+ uint16_t tunnel_dst_port_val;
+ uint8_t unused_0[3];
+ /*
+ * 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_tunnel_dst_port_alloc *
+ ******************************/
+
+
+/* hwrm_tunnel_dst_port_alloc_input (size:192b/24B) */
+struct hwrm_tunnel_dst_port_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Tunnel Type. */
+ uint8_t tunnel_type;
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Enhance Generic Routing Encapsulation (GRE version 1) inside IP datagram payload */
+ #define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_IPGRE_V1 \
+ UINT32_C(0xa)
+ #define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_IPGRE_V1
+ uint8_t unused_0;
+ /*
+ * This field represents the value of L4 destination port used
+ * for the given tunnel type. This field is valid for
+ * specific tunnel types that use layer 4 (e.g. UDP)
+ * transports for tunneling.
+ *
+ * This field is in network byte order.
+ *
+ * A value of 0 shall fail the command.
+ */
+ uint16_t tunnel_dst_port_val;
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_tunnel_dst_port_alloc_output (size:128b/16B) */
+struct hwrm_tunnel_dst_port_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * Identifier of a tunnel L4 destination port value. Only applies to tunnel
+ * types that has l4 destination port parameters.
+ */
+ uint16_t tunnel_dst_port_id;
+ uint8_t unused_0[5];
+ /*
+ * 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_tunnel_dst_port_free *
+ *****************************/
+
+
+/* hwrm_tunnel_dst_port_free_input (size:192b/24B) */
+struct hwrm_tunnel_dst_port_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Tunnel Type. */
+ uint8_t tunnel_type;
+ /* Virtual eXtensible Local Area Network (VXLAN) */
+ #define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN \
+ UINT32_C(0x1)
+ /* Generic Network Virtualization Encapsulation (Geneve) */
+ #define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE \
+ UINT32_C(0x5)
+ /* IPV4 over virtual eXtensible Local Area Network (IPV4oVXLAN) */
+ #define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN_V4 \
+ UINT32_C(0x9)
+ /* Enhance Generic Routing Encapsulation (GRE version 1) inside IP datagram payload */
+ #define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_IPGRE_V1 \
+ UINT32_C(0xa)
+ #define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_LAST \
+ HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_IPGRE_V1
+ uint8_t unused_0;
+ /*
+ * Identifier of a tunnel L4 destination port value. Only applies to tunnel
+ * types that has l4 destination port parameters.
+ */
+ uint16_t tunnel_dst_port_id;
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_tunnel_dst_port_free_output (size:128b/16B) */
+struct hwrm_tunnel_dst_port_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_1[7];
+ /*
+ * 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));
+
+/* ctx_hw_stats (size:1280b/160B) */
+struct ctx_hw_stats {
+ /* Number of received unicast packets */
+ uint64_t rx_ucast_pkts;
+ /* Number of received multicast packets */
+ uint64_t rx_mcast_pkts;
+ /* Number of received broadcast packets */
+ uint64_t rx_bcast_pkts;
+ /* Number of discarded packets on received path */
+ uint64_t rx_discard_pkts;
+ /* Number of dropped packets on received path */
+ uint64_t rx_drop_pkts;
+ /* Number of received bytes for unicast traffic */
+ uint64_t rx_ucast_bytes;
+ /* Number of received bytes for multicast traffic */
+ uint64_t rx_mcast_bytes;
+ /* Number of received bytes for broadcast traffic */
+ uint64_t rx_bcast_bytes;
+ /* Number of transmitted unicast packets */
+ uint64_t tx_ucast_pkts;
+ /* Number of transmitted multicast packets */
+ uint64_t tx_mcast_pkts;
+ /* Number of transmitted broadcast packets */
+ uint64_t tx_bcast_pkts;
+ /* Number of discarded packets on transmit path */
+ uint64_t tx_discard_pkts;
+ /* Number of dropped packets on transmit path */
+ uint64_t tx_drop_pkts;
+ /* Number of transmitted bytes for unicast traffic */
+ uint64_t tx_ucast_bytes;
+ /* Number of transmitted bytes for multicast traffic */
+ uint64_t tx_mcast_bytes;
+ /* Number of transmitted bytes for broadcast traffic */
+ uint64_t tx_bcast_bytes;
+ /* Number of TPA packets */
+ uint64_t tpa_pkts;
+ /* Number of TPA bytes */
+ uint64_t tpa_bytes;
+ /* Number of TPA events */
+ uint64_t tpa_events;
+ /* Number of TPA aborts */
+ uint64_t tpa_aborts;
+} __attribute__((packed));
+
+/***********************
+ * hwrm_stat_ctx_alloc *
+ ***********************/
+
+
+/* hwrm_stat_ctx_alloc_input (size:256b/32B) */
+struct hwrm_stat_ctx_alloc_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* This is the address for statistic block. */
+ uint64_t stats_dma_addr;
+ /*
+ * The statistic block update period in ms.
+ * e.g. 250ms, 500ms, 750ms, 1000ms.
+ * If update_period_ms is 0, then the stats update
+ * shall be never done and the DMA address shall not be used.
+ * In this case, the stat block can only be read by
+ * hwrm_stat_ctx_query command.
+ */
+ uint32_t update_period_ms;
+ /*
+ * This field is used to specify statistics context specific
+ * configuration flags.
+ */
+ uint8_t stat_ctx_flags;
+ /*
+ * When this bit is set to '1', the statistics context shall be
+ * allocated for RoCE traffic only. In this case, traffic other
+ * than offloaded RoCE traffic shall not be included in this
+ * statistic context.
+ * When this bit is set to '0', the statistics context shall be
+ * used for the network traffic other than offloaded RoCE traffic.
+ */
+ #define HWRM_STAT_CTX_ALLOC_INPUT_STAT_CTX_FLAGS_ROCE UINT32_C(0x1)
+ uint8_t unused_0[3];
+} __attribute__((packed));
+
+/* hwrm_stat_ctx_alloc_output (size:128b/16B) */
+struct hwrm_stat_ctx_alloc_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This is the statistics context ID value. */
+ uint32_t stat_ctx_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_stat_ctx_free *
+ **********************/
+
+
+/* hwrm_stat_ctx_free_input (size:192b/24B) */
+struct hwrm_stat_ctx_free_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* ID of the statistics context that is being queried. */
+ uint32_t stat_ctx_id;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_stat_ctx_free_output (size:128b/16B) */
+struct hwrm_stat_ctx_free_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* This is the statistics context ID value. */
+ uint32_t stat_ctx_id;
+ uint8_t unused_0[3];
+ /*
+ * 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_stat_ctx_query *
+ ***********************/
+
+
+/* hwrm_stat_ctx_query_input (size:192b/24B) */
+struct hwrm_stat_ctx_query_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* ID of the statistics context that is being queried. */
+ uint32_t stat_ctx_id;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_stat_ctx_query_output (size:1408b/176B) */
+struct hwrm_stat_ctx_query_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Number of transmitted unicast packets */
+ uint64_t tx_ucast_pkts;
+ /* Number of transmitted multicast packets */
+ uint64_t tx_mcast_pkts;
+ /* Number of transmitted broadcast packets */
+ uint64_t tx_bcast_pkts;
+ /* Number of transmitted packets with error */
+ uint64_t tx_err_pkts;
+ /* Number of dropped packets on transmit path */
+ uint64_t tx_drop_pkts;
+ /* Number of transmitted bytes for unicast traffic */
+ uint64_t tx_ucast_bytes;
+ /* Number of transmitted bytes for multicast traffic */
+ uint64_t tx_mcast_bytes;
+ /* Number of transmitted bytes for broadcast traffic */
+ uint64_t tx_bcast_bytes;
+ /* Number of received unicast packets */
+ uint64_t rx_ucast_pkts;
+ /* Number of received multicast packets */
+ uint64_t rx_mcast_pkts;
+ /* Number of received broadcast packets */
+ uint64_t rx_bcast_pkts;
+ /* Number of received packets with error */
+ uint64_t rx_err_pkts;
+ /* Number of dropped packets on received path */
+ uint64_t rx_drop_pkts;
+ /* Number of received bytes for unicast traffic */
+ uint64_t rx_ucast_bytes;
+ /* Number of received bytes for multicast traffic */
+ uint64_t rx_mcast_bytes;
+ /* Number of received bytes for broadcast traffic */
+ uint64_t rx_bcast_bytes;
+ /* Number of aggregated unicast packets */
+ uint64_t rx_agg_pkts;
+ /* Number of aggregated unicast bytes */
+ uint64_t rx_agg_bytes;
+ /* Number of aggregation events */
+ uint64_t rx_agg_events;
+ /* Number of aborted aggregations */
+ uint64_t rx_agg_aborts;
+ uint8_t unused_0[7];
+ /*
+ * 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_stat_ctx_clr_stats *
+ ***************************/
+
+
+/* hwrm_stat_ctx_clr_stats_input (size:192b/24B) */
+struct hwrm_stat_ctx_clr_stats_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* ID of the statistics context that is being queried. */
+ uint32_t stat_ctx_id;
+ uint8_t unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_stat_ctx_clr_stats_output (size:128b/16B) */
+struct hwrm_stat_ctx_clr_stats_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_pcie_qstats *
+ ********************/
+
+
+/* hwrm_pcie_qstats_input (size:256b/32B) */
+struct hwrm_pcie_qstats_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * The size of PCIe statistics block in bytes.
+ * Firmware will DMA the PCIe statistics to
+ * the host with this field size in the response.
+ */
+ uint16_t pcie_stat_size;
+ uint8_t unused_0[6];
+ /*
+ * This is the host address where
+ * PCIe statistics will be stored
+ */
+ uint64_t pcie_stat_host_addr;
+} __attribute__((packed));
+
+/* hwrm_pcie_qstats_output (size:128b/16B) */
+struct hwrm_pcie_qstats_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* The size of PCIe statistics block in bytes. */
+ uint16_t pcie_stat_size;
+ uint8_t unused_0[5];
+ /*
+ * 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));
+
+/* Port Tx Statistics Formats */
+/* tx_port_stats (size:3264b/408B) */
+struct tx_port_stats {
+ /* Total Number of 64 Bytes frames transmitted */
+ uint64_t tx_64b_frames;
+ /* Total Number of 65-127 Bytes frames transmitted */
+ uint64_t tx_65b_127b_frames;
+ /* Total Number of 128-255 Bytes frames transmitted */
+ uint64_t tx_128b_255b_frames;
+ /* Total Number of 256-511 Bytes frames transmitted */
+ uint64_t tx_256b_511b_frames;
+ /* Total Number of 512-1023 Bytes frames transmitted */
+ uint64_t tx_512b_1023b_frames;
+ /* Total Number of 1024-1518 Bytes frames transmitted */
+ uint64_t tx_1024b_1518_frames;
+ /*
+ * Total Number of each good VLAN (exludes FCS errors)
+ * frame transmitted which is 1519 to 1522 bytes in length
+ * inclusive (excluding framing bits but including FCS bytes).
+ */
+ uint64_t tx_good_vlan_frames;
+ /* Total Number of 1519-2047 Bytes frames transmitted */
+ uint64_t tx_1519b_2047_frames;
+ /* Total Number of 2048-4095 Bytes frames transmitted */
+ uint64_t tx_2048b_4095b_frames;
+ /* Total Number of 4096-9216 Bytes frames transmitted */
+ uint64_t tx_4096b_9216b_frames;
+ /* Total Number of 9217-16383 Bytes frames transmitted */
+ uint64_t tx_9217b_16383b_frames;
+ /* Total Number of good frames transmitted */
+ uint64_t tx_good_frames;
+ /* Total Number of frames transmitted */
+ uint64_t tx_total_frames;
+ /* Total number of unicast frames transmitted */
+ uint64_t tx_ucast_frames;
+ /* Total number of multicast frames transmitted */
+ uint64_t tx_mcast_frames;
+ /* Total number of broadcast frames transmitted */
+ uint64_t tx_bcast_frames;
+ /* Total number of PAUSE control frames transmitted */
+ uint64_t tx_pause_frames;
+ /*
+ * Total number of PFC/per-priority PAUSE
+ * control frames transmitted
+ */
+ uint64_t tx_pfc_frames;
+ /* Total number of jabber frames transmitted */
+ uint64_t tx_jabber_frames;
+ /* Total number of frames transmitted with FCS error */
+ uint64_t tx_fcs_err_frames;
+ /* Total number of control frames transmitted */
+ uint64_t tx_control_frames;
+ /* Total number of over-sized frames transmitted */
+ uint64_t tx_oversz_frames;
+ /* Total number of frames with single deferral */
+ uint64_t tx_single_dfrl_frames;
+ /* Total number of frames with multiple deferrals */
+ uint64_t tx_multi_dfrl_frames;
+ /* Total number of frames with single collision */
+ uint64_t tx_single_coll_frames;
+ /* Total number of frames with multiple collisions */
+ uint64_t tx_multi_coll_frames;
+ /* Total number of frames with late collisions */
+ uint64_t tx_late_coll_frames;
+ /* Total number of frames with excessive collisions */
+ uint64_t tx_excessive_coll_frames;
+ /* Total number of fragmented frames transmitted */
+ uint64_t tx_frag_frames;
+ /* Total number of transmit errors */
+ uint64_t tx_err;
+ /* Total number of single VLAN tagged frames transmitted */
+ uint64_t tx_tagged_frames;
+ /* Total number of double VLAN tagged frames transmitted */
+ uint64_t tx_dbl_tagged_frames;
+ /* Total number of runt frames transmitted */
+ uint64_t tx_runt_frames;
+ /* Total number of TX FIFO under runs */
+ uint64_t tx_fifo_underruns;
+ /*
+ * Total number of PFC frames with PFC enabled bit for
+ * Pri 0 transmitted
+ */
+ uint64_t tx_pfc_ena_frames_pri0;
+ /*
+ * Total number of PFC frames with PFC enabled bit for
+ * Pri 1 transmitted
+ */
+ uint64_t tx_pfc_ena_frames_pri1;
+ /*
+ * Total number of PFC frames with PFC enabled bit for
+ * Pri 2 transmitted
+ */
+ uint64_t tx_pfc_ena_frames_pri2;
+ /*
+ * Total number of PFC frames with PFC enabled bit for
+ * Pri 3 transmitted
+ */
+ uint64_t tx_pfc_ena_frames_pri3;
+ /*
+ * Total number of PFC frames with PFC enabled bit for
+ * Pri 4 transmitted
+ */
+ uint64_t tx_pfc_ena_frames_pri4;
+ /*
+ * Total number of PFC frames with PFC enabled bit for
+ * Pri 5 transmitted
+ */
+ uint64_t tx_pfc_ena_frames_pri5;
+ /*
+ * Total number of PFC frames with PFC enabled bit for
+ * Pri 6 transmitted
+ */
+ uint64_t tx_pfc_ena_frames_pri6;
+ /*
+ * Total number of PFC frames with PFC enabled bit for
+ * Pri 7 transmitted
+ */
+ uint64_t tx_pfc_ena_frames_pri7;
+ /* Total number of EEE LPI Events on TX */
+ uint64_t tx_eee_lpi_events;
+ /* EEE LPI Duration Counter on TX */
+ uint64_t tx_eee_lpi_duration;
+ /*
+ * Total number of Link Level Flow Control (LLFC) messages
+ * transmitted
+ */
+ uint64_t tx_llfc_logical_msgs;
+ /* Total number of HCFC messages transmitted */
+ uint64_t tx_hcfc_msgs;
+ /* Total number of TX collisions */
+ uint64_t tx_total_collisions;
+ /* Total number of transmitted bytes */
+ uint64_t tx_bytes;
+ /* Total number of end-to-end HOL frames */
+ uint64_t tx_xthol_frames;
+ /* Total Tx Drops per Port reported by STATS block */
+ uint64_t tx_stat_discard;
+ /* Total Tx Error Drops per Port reported by STATS block */
+ uint64_t tx_stat_error;
+} __attribute__((packed));
+
+/* Port Rx Statistics Formats */
+/* rx_port_stats (size:4224b/528B) */
+struct rx_port_stats {
+ /* Total Number of 64 Bytes frames received */
+ uint64_t rx_64b_frames;
+ /* Total Number of 65-127 Bytes frames received */
+ uint64_t rx_65b_127b_frames;
+ /* Total Number of 128-255 Bytes frames received */
+ uint64_t rx_128b_255b_frames;
+ /* Total Number of 256-511 Bytes frames received */
+ uint64_t rx_256b_511b_frames;
+ /* Total Number of 512-1023 Bytes frames received */
+ uint64_t rx_512b_1023b_frames;
+ /* Total Number of 1024-1518 Bytes frames received */
+ uint64_t rx_1024b_1518_frames;
+ /*
+ * Total Number of each good VLAN (exludes FCS errors)
+ * frame received which is 1519 to 1522 bytes in length
+ * inclusive (excluding framing bits but including FCS bytes).
+ */
+ uint64_t rx_good_vlan_frames;
+ /* Total Number of 1519-2047 Bytes frames received */
+ uint64_t rx_1519b_2047b_frames;
+ /* Total Number of 2048-4095 Bytes frames received */
+ uint64_t rx_2048b_4095b_frames;
+ /* Total Number of 4096-9216 Bytes frames received */
+ uint64_t rx_4096b_9216b_frames;
+ /* Total Number of 9217-16383 Bytes frames received */
+ uint64_t rx_9217b_16383b_frames;
+ /* Total number of frames received */
+ uint64_t rx_total_frames;
+ /* Total number of unicast frames received */
+ uint64_t rx_ucast_frames;
+ /* Total number of multicast frames received */
+ uint64_t rx_mcast_frames;
+ /* Total number of broadcast frames received */
+ uint64_t rx_bcast_frames;
+ /* Total number of received frames with FCS error */
+ uint64_t rx_fcs_err_frames;
+ /* Total number of control frames received */
+ uint64_t rx_ctrl_frames;
+ /* Total number of PAUSE frames received */
+ uint64_t rx_pause_frames;
+ /* Total number of PFC frames received */
+ uint64_t rx_pfc_frames;
+ /*
+ * Total number of frames received with an unsupported
+ * opcode
+ */
+ uint64_t rx_unsupported_opcode_frames;
+ /*
+ * Total number of frames received with an unsupported
+ * DA for pause and PFC
+ */
+ uint64_t rx_unsupported_da_pausepfc_frames;
+ /* Total number of frames received with an unsupported SA */
+ uint64_t rx_wrong_sa_frames;
+ /* Total number of received packets with alignment error */
+ uint64_t rx_align_err_frames;
+ /* Total number of received frames with out-of-range length */
+ uint64_t rx_oor_len_frames;
+ /* Total number of received frames with error termination */
+ uint64_t rx_code_err_frames;
+ /*
+ * Total number of received frames with a false carrier is
+ * detected during idle, as defined by RX_ER samples active
+ * and RXD is 0xE. The event is reported along with the
+ * statistics generated on the next received frame. Only
+ * one false carrier condition can be detected and logged
+ * between frames.
+ *
+ * Carrier event, valid for 10M/100M speed modes only.
+ */
+ uint64_t rx_false_carrier_frames;
+ /* Total number of over-sized frames received */
+ uint64_t rx_ovrsz_frames;
+ /* Total number of jabber packets received */
+ uint64_t rx_jbr_frames;
+ /* Total number of received frames with MTU error */
+ uint64_t rx_mtu_err_frames;
+ /* Total number of received frames with CRC match */
+ uint64_t rx_match_crc_frames;
+ /* Total number of frames received promiscuously */
+ uint64_t rx_promiscuous_frames;
+ /*
+ * Total number of received frames with one or two VLAN
+ * tags
+ */
+ uint64_t rx_tagged_frames;
+ /* Total number of received frames with two VLAN tags */
+ uint64_t rx_double_tagged_frames;
+ /* Total number of truncated frames received */
+ uint64_t rx_trunc_frames;
+ /* Total number of good frames (without errors) received */
+ uint64_t rx_good_frames;
+ /*
+ * Total number of received PFC frames with transition from
+ * XON to XOFF on Pri 0
+ */
+ uint64_t rx_pfc_xon2xoff_frames_pri0;
+ /*
+ * Total number of received PFC frames with transition from
+ * XON to XOFF on Pri 1
+ */
+ uint64_t rx_pfc_xon2xoff_frames_pri1;
+ /*
+ * Total number of received PFC frames with transition from
+ * XON to XOFF on Pri 2
+ */
+ uint64_t rx_pfc_xon2xoff_frames_pri2;
+ /*
+ * Total number of received PFC frames with transition from
+ * XON to XOFF on Pri 3
+ */
+ uint64_t rx_pfc_xon2xoff_frames_pri3;
+ /*
+ * Total number of received PFC frames with transition from
+ * XON to XOFF on Pri 4
+ */
+ uint64_t rx_pfc_xon2xoff_frames_pri4;
+ /*
+ * Total number of received PFC frames with transition from
+ * XON to XOFF on Pri 5
+ */
+ uint64_t rx_pfc_xon2xoff_frames_pri5;
+ /*
+ * Total number of received PFC frames with transition from
+ * XON to XOFF on Pri 6
+ */
+ uint64_t rx_pfc_xon2xoff_frames_pri6;
+ /*
+ * Total number of received PFC frames with transition from
+ * XON to XOFF on Pri 7
+ */
+ uint64_t rx_pfc_xon2xoff_frames_pri7;
+ /*
+ * Total number of received PFC frames with PFC enabled
+ * bit for Pri 0
+ */
+ uint64_t rx_pfc_ena_frames_pri0;
+ /*
+ * Total number of received PFC frames with PFC enabled
+ * bit for Pri 1
+ */
+ uint64_t rx_pfc_ena_frames_pri1;
+ /*
+ * Total number of received PFC frames with PFC enabled
+ * bit for Pri 2
+ */
+ uint64_t rx_pfc_ena_frames_pri2;
+ /*
+ * Total number of received PFC frames with PFC enabled
+ * bit for Pri 3
+ */
+ uint64_t rx_pfc_ena_frames_pri3;
+ /*
+ * Total number of received PFC frames with PFC enabled
+ * bit for Pri 4
+ */
+ uint64_t rx_pfc_ena_frames_pri4;
+ /*
+ * Total number of received PFC frames with PFC enabled
+ * bit for Pri 5
+ */
+ uint64_t rx_pfc_ena_frames_pri5;
+ /*
+ * Total number of received PFC frames with PFC enabled
+ * bit for Pri 6
+ */
+ uint64_t rx_pfc_ena_frames_pri6;
+ /*
+ * Total number of received PFC frames with PFC enabled
+ * bit for Pri 7
+ */
+ uint64_t rx_pfc_ena_frames_pri7;
+ /* Total Number of frames received with SCH CRC error */
+ uint64_t rx_sch_crc_err_frames;
+ /* Total Number of under-sized frames received */
+ uint64_t rx_undrsz_frames;
+ /* Total Number of fragmented frames received */
+ uint64_t rx_frag_frames;
+ /* Total number of RX EEE LPI Events */
+ uint64_t rx_eee_lpi_events;
+ /* EEE LPI Duration Counter on RX */
+ uint64_t rx_eee_lpi_duration;
+ /*
+ * Total number of physical type Link Level Flow Control
+ * (LLFC) messages received
+ */
+ uint64_t rx_llfc_physical_msgs;
+ /*
+ * Total number of logical type Link Level Flow Control
+ * (LLFC) messages received
+ */
+ uint64_t rx_llfc_logical_msgs;
+ /*
+ * Total number of logical type Link Level Flow Control
+ * (LLFC) messages received with CRC error
+ */
+ uint64_t rx_llfc_msgs_with_crc_err;
+ /* Total number of HCFC messages received */
+ uint64_t rx_hcfc_msgs;
+ /* Total number of HCFC messages received with CRC error */
+ uint64_t rx_hcfc_msgs_with_crc_err;
+ /* Total number of received bytes */
+ uint64_t rx_bytes;
+ /* Total number of bytes received in runt frames */
+ uint64_t rx_runt_bytes;
+ /* Total number of runt frames received */
+ uint64_t rx_runt_frames;
+ /* Total Rx Discards per Port reported by STATS block */
+ uint64_t rx_stat_discard;
+ uint64_t rx_stat_err;
+} __attribute__((packed));
+
+/* Port Rx Statistics extended Formats */
+/* rx_port_stats_ext (size:320b/40B) */
+struct rx_port_stats_ext {
+ /* Number of times link state changed to down */
+ uint64_t link_down_events;
+ /* Number of times the idle rings with pause bit are found */
+ uint64_t continuous_pause_events;
+ /* Number of times the active rings pause bit resumed back */
+ uint64_t resume_pause_events;
+ /* Number of times, the ROCE cos queue PFC is disabled to avoid pause flood/burst */
+ uint64_t continuous_roce_pause_events;
+ /* Number of times, the ROCE cos queue PFC is enabled back */
+ uint64_t resume_roce_pause_events;
+} __attribute__((packed));
+
+/* PCIe Statistics Formats */
+/* pcie_ctx_hw_stats (size:768b/96B) */
+struct pcie_ctx_hw_stats {
+ /* Number of physical layer receiver errors */
+ uint64_t pcie_pl_signal_integrity;
+ /* Number of DLLP CRC errors detected by Data Link Layer */
+ uint64_t pcie_dl_signal_integrity;
+ /*
+ * Number of TLP LCRC and sequence number errors detected
+ * by Data Link Layer
+ */
+ uint64_t pcie_tl_signal_integrity;
+ /* Number of times LTSSM entered Recovery state */
+ uint64_t pcie_link_integrity;
+ /* Number of TLP bytes that have been trasmitted */
+ uint64_t pcie_tx_traffic_rate;
+ /* Number of TLP bytes that have been received */
+ uint64_t pcie_rx_traffic_rate;
+ /* Number of DLLP bytes that have been trasmitted */
+ uint64_t pcie_tx_dllp_statistics;
+ /* Number of DLLP bytes that have been received */
+ uint64_t pcie_rx_dllp_statistics;
+ /*
+ * Number of times spent in each phase of gen3
+ * equalization
+ */
+ uint64_t pcie_equalization_time;
+ /* Records the last 16 transitions of the LTSSM */
+ uint32_t pcie_ltssm_histogram[4];
+ /*
+ * Record the last 8 reasons on why LTSSM transitioned
+ * to Recovery
+ */
+ uint64_t pcie_recovery_histogram;
+} __attribute__((packed));
+
+/**********************
+ * hwrm_exec_fwd_resp *
+ **********************/
+
+
+/* hwrm_exec_fwd_resp_input (size:1024b/128B) */
+struct hwrm_exec_fwd_resp_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This is an encapsulated request. This request should
+ * be executed by the HWRM and the response should be
+ * provided in the response buffer inside the encapsulated
+ * request.
+ */
+ uint32_t encap_request[26];
+ /*
+ * This value indicates the target id of the response to
+ * the encapsulated request.
+ * 0x0 - 0xFFF8 - Used for function ids
+ * 0xFFF8 - 0xFFFE - Reserved for internal processors
+ * 0xFFFF - HWRM
+ */
+ uint16_t encap_resp_target_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_exec_fwd_resp_output (size:128b/16B) */
+struct hwrm_exec_fwd_resp_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_reject_fwd_resp *
+ ************************/
+
+
+/* hwrm_reject_fwd_resp_input (size:1024b/128B) */
+struct hwrm_reject_fwd_resp_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This is an encapsulated request. This request should
+ * be rejected by the HWRM and the error response should be
+ * provided in the response buffer inside the encapsulated
+ * request.
+ */
+ uint32_t encap_request[26];
+ /*
+ * This value indicates the target id of the response to
+ * the encapsulated request.
+ * 0x0 - 0xFFF8 - Used for function ids
+ * 0xFFF8 - 0xFFFE - Reserved for internal processors
+ * 0xFFFF - HWRM
+ */
+ uint16_t encap_resp_target_id;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_reject_fwd_resp_output (size:128b/16B) */
+struct hwrm_reject_fwd_resp_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_fwd_resp *
+ *****************/
+
+
+/* hwrm_fwd_resp_input (size:1024b/128B) */
+struct hwrm_fwd_resp_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This value indicates the target id of the encapsulated
+ * response.
+ * 0x0 - 0xFFF8 - Used for function ids
+ * 0xFFF8 - 0xFFFE - Reserved for internal processors
+ * 0xFFFF - HWRM
+ */
+ uint16_t encap_resp_target_id;
+ /*
+ * This value indicates the completion ring the encapsulated
+ * response will be optionally completed on. If the value is
+ * -1, then no CR completion shall be generated for the
+ * encapsulated response. Any other value must be a
+ * valid CR ring_id value. If a valid encap_resp_cmpl_ring
+ * is provided, then a CR completion shall be generated for
+ * the encapsulated response.
+ */
+ uint16_t encap_resp_cmpl_ring;
+ /* This field indicates the length of encapsulated response. */
+ uint16_t encap_resp_len;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ /*
+ * This is the host address where the encapsulated response
+ * will be written.
+ * This area must be 16B aligned and must be cleared to zero
+ * before the original request is made.
+ */
+ uint64_t encap_resp_addr;
+ /* This is an encapsulated response. */
+ uint32_t encap_resp[24];
+} __attribute__((packed));
+
+/* hwrm_fwd_resp_output (size:128b/16B) */
+struct hwrm_fwd_resp_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_fwd_async_event_cmpl *
+ *****************************/
+
+
+/* hwrm_fwd_async_event_cmpl_input (size:320b/40B) */
+struct hwrm_fwd_async_event_cmpl_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This value indicates the target id of the encapsulated
+ * asynchronous event.
+ * 0x0 - 0xFFF8 - Used for function ids
+ * 0xFFF8 - 0xFFFE - Reserved for internal processors
+ * 0xFFFF - Broadcast to all children VFs (only applicable when
+ * a PF is the requester)
+ */
+ uint16_t encap_async_event_target_id;
+ uint8_t unused_0[6];
+ /* This is an encapsulated asynchronous event completion. */
+ uint32_t encap_async_event_cmpl[4];
+} __attribute__((packed));
+
+/* hwrm_fwd_async_event_cmpl_output (size:128b/16B) */
+struct hwrm_fwd_async_event_cmpl_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_raw_write_blk *
+ **************************/
+
+
+/* hwrm_nvm_raw_write_blk_input (size:256b/32B) */
+struct hwrm_nvm_raw_write_blk_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * 64-bit Host Source Address.
+ * This is the loation of the source data to be written.
+ */
+ uint64_t host_src_addr;
+ /*
+ * 32-bit Destination Address.
+ * This is the NVRAM byte-offset where the source data will be written to.
+ */
+ uint32_t dest_addr;
+ /* Length of data to be written, in bytes. */
+ uint32_t len;
+} __attribute__((packed));
+
+/* hwrm_nvm_raw_write_blk_output (size:128b/16B) */
+struct hwrm_nvm_raw_write_blk_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_read *
+ *****************/
+
+
+/* hwrm_nvm_read_input (size:320b/40B) */
+struct hwrm_nvm_read_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * 64-bit Host Destination Address.
+ * This is the host address where the data will be written to.
+ */
+ uint64_t host_dest_addr;
+ /* The 0-based index of the directory entry. */
+ uint16_t dir_idx;
+ uint8_t unused_0[2];
+ /* The NVRAM byte-offset to read from. */
+ uint32_t offset;
+ /* The length of the data to be read, in bytes. */
+ uint32_t len;
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_nvm_read_output (size:128b/16B) */
+struct hwrm_nvm_read_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_raw_dump *
+ *********************/
+
+
+/* hwrm_nvm_raw_dump_input (size:256b/32B) */
+struct hwrm_nvm_raw_dump_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * 64-bit Host Destination Address.
+ * This is the host address where the data will be written to.
+ */
+ uint64_t host_dest_addr;
+ /* 32-bit NVRAM byte-offset to read from. */
+ uint32_t offset;
+ /* Total length of NVRAM contents to be read, in bytes. */
+ uint32_t len;
+} __attribute__((packed));
+
+/* hwrm_nvm_raw_dump_output (size:128b/16B) */
+struct hwrm_nvm_raw_dump_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_get_dir_entries *
+ ****************************/
+
+
+/* hwrm_nvm_get_dir_entries_input (size:192b/24B) */
+struct hwrm_nvm_get_dir_entries_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * 64-bit Host Destination Address.
+ * This is the host address where the directory will be written.
+ */
+ uint64_t host_dest_addr;
+} __attribute__((packed));
+
+/* hwrm_nvm_get_dir_entries_output (size:128b/16B) */
+struct hwrm_nvm_get_dir_entries_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_get_dir_info *
+ *************************/
+
+
+/* hwrm_nvm_get_dir_info_input (size:128b/16B) */
+struct hwrm_nvm_get_dir_info_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+/* hwrm_nvm_get_dir_info_output (size:192b/24B) */
+struct hwrm_nvm_get_dir_info_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Number of directory entries in the directory. */
+ uint32_t entries;
+ /* Size of each directory entry, in bytes. */
+ uint32_t entry_length;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_write *
+ ******************/
+
+
+/* hwrm_nvm_write_input (size:384b/48B) */
+struct hwrm_nvm_write_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * 64-bit Host Source Address.
+ * This is where the source data is.
+ */
+ uint64_t host_src_addr;
+ /* The Directory Entry Type (valid values are defined in the bnxnvm_directory_type enum defined in the file bnxnvm_defs.h). */
+ uint16_t dir_type;
+ /*
+ * Directory ordinal.
+ * The 0-based instance of the combined Directory Entry Type and Extension.
+ */
+ uint16_t dir_ordinal;
+ /* The Directory Entry Extension flags (see BNX_DIR_EXT_* in the file bnxnvm_defs.h). */
+ uint16_t dir_ext;
+ /* Directory Entry Attribute flags (see BNX_DIR_ATTR_* in the file bnxnvm_defs.h). */
+ uint16_t dir_attr;
+ /*
+ * Length of data to write, in bytes. May be less than or equal to the allocated size for the directory entry.
+ * The data length stored in the directory entry will be updated to reflect this value once the write is complete.
+ */
+ uint32_t dir_data_length;
+ /* Option. */
+ uint16_t option;
+ uint16_t flags;
+ /*
+ * When this bit is '1', the original active image
+ * will not be removed. TBD: what purpose is this?
+ */
+ #define HWRM_NVM_WRITE_INPUT_FLAGS_KEEP_ORIG_ACTIVE_IMG \
+ UINT32_C(0x1)
+ /*
+ * The requested length of the allocated NVM for the item, in bytes. This value may be greater than or equal to the specified data length (dir_data_length).
+ * If this value is less than the specified data length, it will be ignored.
+ * The response will contain the actual allocated item length, which may be greater than the requested item length.
+ * The purpose for allocating more than the required number of bytes for an item's data is to pre-allocate extra storage (padding) to accomodate
+ * the potential future growth of an item (e.g. upgraded firmware with a size increase, log growth, expanded configuration data).
+ */
+ uint32_t dir_item_length;
+ uint32_t unused_0;
+} __attribute__((packed));
+
+/* hwrm_nvm_write_output (size:128b/16B) */
+struct hwrm_nvm_write_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * Length of the allocated NVM for the item, in bytes. The value may be greater than or equal to the specified data length or the requested item length.
+ * The actual item length used when creating a new directory entry will be a multiple of an NVM block size.
+ */
+ uint32_t dir_item_length;
+ /* The directory index of the created or modified item. */
+ uint16_t dir_idx;
+ uint8_t unused_0;
+ /*
+ * 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_nvm_write_cmd_err (size:64b/8B) */
+struct hwrm_nvm_write_cmd_err {
+ /*
+ * command specific error codes that goes to
+ * the cmd_err field in Common HWRM Error Response.
+ */
+ uint8_t code;
+ /* Unknown error */
+ #define HWRM_NVM_WRITE_CMD_ERR_CODE_UNKNOWN UINT32_C(0x0)
+ /* Unable to complete operation due to fragmentation */
+ #define HWRM_NVM_WRITE_CMD_ERR_CODE_FRAG_ERR UINT32_C(0x1)
+ /* nvm is completely full. */
+ #define HWRM_NVM_WRITE_CMD_ERR_CODE_NO_SPACE UINT32_C(0x2)
+ #define HWRM_NVM_WRITE_CMD_ERR_CODE_LAST \
+ HWRM_NVM_WRITE_CMD_ERR_CODE_NO_SPACE
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/*******************
+ * hwrm_nvm_modify *
+ *******************/
+
+
+/* hwrm_nvm_modify_input (size:320b/40B) */
+struct hwrm_nvm_modify_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * 64-bit Host Source Address.
+ * This is where the modified data is.
+ */
+ uint64_t host_src_addr;
+ /* 16-bit directory entry index. */
+ uint16_t dir_idx;
+ uint8_t unused_0[2];
+ /* 32-bit NVRAM byte-offset to modify content from. */
+ uint32_t offset;
+ /*
+ * Length of data to be modified, in bytes. The length shall
+ * be non-zero.
+ */
+ uint32_t len;
+ uint8_t unused_1[4];
+} __attribute__((packed));
+
+/* hwrm_nvm_modify_output (size:128b/16B) */
+struct hwrm_nvm_modify_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_find_dir_entry *
+ ***************************/
+
+
+/* hwrm_nvm_find_dir_entry_input (size:256b/32B) */
+struct hwrm_nvm_find_dir_entry_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the dir_idx_valid field to be
+ * configured.
+ */
+ #define HWRM_NVM_FIND_DIR_ENTRY_INPUT_ENABLES_DIR_IDX_VALID \
+ UINT32_C(0x1)
+ /* Directory Entry Index */
+ uint16_t dir_idx;
+ /* Directory Entry (Image) Type */
+ uint16_t dir_type;
+ /*
+ * Directory ordinal.
+ * The instance of this Directory Type
+ */
+ uint16_t dir_ordinal;
+ /* The Directory Entry Extension flags. */
+ uint16_t dir_ext;
+ /* This value indicates the search option using dir_ordinal. */
+ uint8_t opt_ordinal;
+ /* This value indicates the search option using dir_ordinal. */
+ #define HWRM_NVM_FIND_DIR_ENTRY_INPUT_OPT_ORDINAL_MASK UINT32_C(0x3)
+ #define HWRM_NVM_FIND_DIR_ENTRY_INPUT_OPT_ORDINAL_SFT 0
+ /* Equal to specified ordinal value. */
+ #define HWRM_NVM_FIND_DIR_ENTRY_INPUT_OPT_ORDINAL_EQ UINT32_C(0x0)
+ /* Greater than or equal to specified ordinal value */
+ #define HWRM_NVM_FIND_DIR_ENTRY_INPUT_OPT_ORDINAL_GE UINT32_C(0x1)
+ /* Greater than specified ordinal value */
+ #define HWRM_NVM_FIND_DIR_ENTRY_INPUT_OPT_ORDINAL_GT UINT32_C(0x2)
+ #define HWRM_NVM_FIND_DIR_ENTRY_INPUT_OPT_ORDINAL_LAST \
+ HWRM_NVM_FIND_DIR_ENTRY_INPUT_OPT_ORDINAL_GT
+ uint8_t unused_0[3];
+} __attribute__((packed));
+
+/* hwrm_nvm_find_dir_entry_output (size:256b/32B) */
+struct hwrm_nvm_find_dir_entry_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Allocated NVRAM for this directory entry, in bytes. */
+ uint32_t dir_item_length;
+ /* Size of the stored data for this directory entry, in bytes. */
+ uint32_t dir_data_length;
+ /*
+ * Firmware version.
+ * Only valid if the directory entry is for embedded firmware stored in APE_BIN Format.
+ */
+ uint32_t fw_ver;
+ /* Directory ordinal. */
+ uint16_t dir_ordinal;
+ /* Directory Entry Index */
+ uint16_t dir_idx;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_erase_dir_entry *
+ ****************************/
+
+
+/* hwrm_nvm_erase_dir_entry_input (size:192b/24B) */
+struct hwrm_nvm_erase_dir_entry_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Directory Entry Index */
+ uint16_t dir_idx;
+ uint8_t unused_0[6];
+} __attribute__((packed));
+
+/* hwrm_nvm_erase_dir_entry_output (size:128b/16B) */
+struct hwrm_nvm_erase_dir_entry_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_get_dev_info *
+ *************************/
+
+
+/* hwrm_nvm_get_dev_info_input (size:128b/16B) */
+struct hwrm_nvm_get_dev_info_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+/* hwrm_nvm_get_dev_info_output (size:256b/32B) */
+struct hwrm_nvm_get_dev_info_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* Manufacturer ID. */
+ uint16_t manufacturer_id;
+ /* Device ID. */
+ uint16_t device_id;
+ /* Sector size of the NVRAM device. */
+ uint32_t sector_size;
+ /* Total size, in bytes of the NVRAM device. */
+ uint32_t nvram_size;
+ uint32_t reserved_size;
+ /* Available size that can be used, in bytes. Available size is the NVRAM size take away the used size and reserved size. */
+ uint32_t available_size;
+ uint8_t unused_0[3];
+ /*
+ * 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_nvm_mod_dir_entry *
+ **************************/
+
+
+/* hwrm_nvm_mod_dir_entry_input (size:256b/32B) */
+struct hwrm_nvm_mod_dir_entry_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ uint32_t enables;
+ /*
+ * This bit must be '1' for the checksum field to be
+ * configured.
+ */
+ #define HWRM_NVM_MOD_DIR_ENTRY_INPUT_ENABLES_CHECKSUM UINT32_C(0x1)
+ /* Directory Entry Index */
+ uint16_t dir_idx;
+ /*
+ * Directory ordinal.
+ * The (0-based) instance of this Directory Type.
+ */
+ uint16_t dir_ordinal;
+ /* The Directory Entry Extension flags (see BNX_DIR_EXT_* for extension flag definitions). */
+ uint16_t dir_ext;
+ /* Directory Entry Attribute flags (see BNX_DIR_ATTR_* for attribute flag definitions). */
+ uint16_t dir_attr;
+ /*
+ * If valid, then this field updates the checksum
+ * value of the content in the directory entry.
+ */
+ uint32_t checksum;
+} __attribute__((packed));
+
+/* hwrm_nvm_mod_dir_entry_output (size:128b/16B) */
+struct hwrm_nvm_mod_dir_entry_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_verify_update *
+ **************************/
+
+
+/* hwrm_nvm_verify_update_input (size:192b/24B) */
+struct hwrm_nvm_verify_update_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* Directory Entry Type, to be verified. */
+ uint16_t dir_type;
+ /*
+ * Directory ordinal.
+ * The instance of the Directory Type to be verified.
+ */
+ uint16_t dir_ordinal;
+ /*
+ * The Directory Entry Extension flags.
+ * The "UPDATE" extension flag must be set in this value.
+ * A corresponding directory entry with the same type and ordinal values but *without*
+ * the "UPDATE" extension flag must also exist. The other flags of the extension must
+ * be identical between the active and update entries.
+ */
+ uint16_t dir_ext;
+ uint8_t unused_0[2];
+} __attribute__((packed));
+
+/* hwrm_nvm_verify_update_output (size:128b/16B) */
+struct hwrm_nvm_verify_update_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_install_update *
+ ***************************/
+
+
+/* hwrm_nvm_install_update_input (size:192b/24B) */
+struct hwrm_nvm_install_update_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * Installation type. If the value 3 through 0xffff is used,
+ * only packaged items with that type value will be installed and
+ * conditional installation directives for those packaged items
+ * will be over-ridden (i.e. 'create' or 'replace' will be treated
+ * as 'install').
+ */
+ uint32_t install_type;
+ /*
+ * Perform a normal package installation. Conditional installation
+ * directives (e.g. 'create' and 'replace') of packaged items
+ * will be followed.
+ */
+ #define HWRM_NVM_INSTALL_UPDATE_INPUT_INSTALL_TYPE_NORMAL UINT32_C(0x0)
+ /*
+ * Install all packaged items regardless of installation directive
+ * (i.e. treat all packaged items as though they have an installation
+ * directive of 'install').
+ */
+ #define HWRM_NVM_INSTALL_UPDATE_INPUT_INSTALL_TYPE_ALL \
+ UINT32_C(0xffffffff)
+ #define HWRM_NVM_INSTALL_UPDATE_INPUT_INSTALL_TYPE_LAST \
+ HWRM_NVM_INSTALL_UPDATE_INPUT_INSTALL_TYPE_ALL
+ uint16_t flags;
+ /* If set to 1, then securely erase all unused locations in persistent storage. */
+ #define HWRM_NVM_INSTALL_UPDATE_INPUT_FLAGS_ERASE_UNUSED_SPACE \
+ UINT32_C(0x1)
+ /*
+ * If set to 1, then unspecifed images, images not in the package file, will be safely deleted.
+ * When combined with erase_unused_space then unspecified images will be securely erased.
+ */
+ #define HWRM_NVM_INSTALL_UPDATE_INPUT_FLAGS_REMOVE_UNUSED_PKG \
+ UINT32_C(0x2)
+ /*
+ * If set to 1, FW will defragment the NVM if defragmentation is required for the update.
+ * Allow additional time for this command to complete if this bit is set to 1.
+ */
+ #define HWRM_NVM_INSTALL_UPDATE_INPUT_FLAGS_ALLOWED_TO_DEFRAG \
+ UINT32_C(0x4)
+ uint8_t unused_0[2];
+} __attribute__((packed));
+
+/* hwrm_nvm_install_update_output (size:192b/24B) */
+struct hwrm_nvm_install_update_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /*
+ * Bit-mask of successfully installed items.
+ * Bit-0 corresponding to the first packaged item, Bit-1 for the second item, etc.
+ * A value of 0 indicates that no items were successfully installed.
+ */
+ uint64_t installed_items;
+ /* result is 8 b */
+ uint8_t result;
+ /* There was no problem with the package installation. */
+ #define HWRM_NVM_INSTALL_UPDATE_OUTPUT_RESULT_SUCCESS UINT32_C(0x0)
+ #define HWRM_NVM_INSTALL_UPDATE_OUTPUT_RESULT_LAST \
+ HWRM_NVM_INSTALL_UPDATE_OUTPUT_RESULT_SUCCESS
+ /* problem_item is 8 b */
+ uint8_t problem_item;
+ /* There was no problem with any packaged items. */
+ #define HWRM_NVM_INSTALL_UPDATE_OUTPUT_PROBLEM_ITEM_NONE \
+ UINT32_C(0x0)
+ /* There was a problem with the NVM package itself. */
+ #define HWRM_NVM_INSTALL_UPDATE_OUTPUT_PROBLEM_ITEM_PACKAGE \
+ UINT32_C(0xff)
+ #define HWRM_NVM_INSTALL_UPDATE_OUTPUT_PROBLEM_ITEM_LAST \
+ HWRM_NVM_INSTALL_UPDATE_OUTPUT_PROBLEM_ITEM_PACKAGE
+ /* reset_required is 8 b */
+ uint8_t reset_required;
+ /*
+ * No reset is required for installed/updated firmware or
+ * microcode to take effect.
+ */
+ #define HWRM_NVM_INSTALL_UPDATE_OUTPUT_RESET_REQUIRED_NONE \
+ UINT32_C(0x0)
+ /*
+ * A PCIe reset (e.g. system reboot) is
+ * required for newly installed/updated firmware or
+ * microcode to take effect.
+ */
+ #define HWRM_NVM_INSTALL_UPDATE_OUTPUT_RESET_REQUIRED_PCI \
+ UINT32_C(0x1)
+ /*
+ * A controller power reset (e.g. system power-cycle) is
+ * required for newly installed/updated firmware or
+ * microcode to take effect. Some newly installed/updated
+ * firmware or microcode may still take effect upon the
+ * next PCIe reset.
+ */
+ #define HWRM_NVM_INSTALL_UPDATE_OUTPUT_RESET_REQUIRED_POWER \
+ UINT32_C(0x2)
+ #define HWRM_NVM_INSTALL_UPDATE_OUTPUT_RESET_REQUIRED_LAST \
+ HWRM_NVM_INSTALL_UPDATE_OUTPUT_RESET_REQUIRED_POWER
+ uint8_t unused_0[4];
+ /*
+ * 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_nvm_install_update_cmd_err (size:64b/8B) */
+struct hwrm_nvm_install_update_cmd_err {
+ /*
+ * command specific error codes that goes to
+ * the cmd_err field in Common HWRM Error Response.
+ */
+ uint8_t code;
+ /* Unknown error */
+ #define HWRM_NVM_INSTALL_UPDATE_CMD_ERR_CODE_UNKNOWN UINT32_C(0x0)
+ /* Unable to complete operation due to fragmentation */
+ #define HWRM_NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR UINT32_C(0x1)
+ /* nvm is completely full. */
+ #define HWRM_NVM_INSTALL_UPDATE_CMD_ERR_CODE_NO_SPACE UINT32_C(0x2)
+ #define HWRM_NVM_INSTALL_UPDATE_CMD_ERR_CODE_LAST \
+ HWRM_NVM_INSTALL_UPDATE_CMD_ERR_CODE_NO_SPACE
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/******************
+ * hwrm_nvm_flush *
+ ******************/
+
+
+/* hwrm_nvm_flush_input (size:128b/16B) */
+struct hwrm_nvm_flush_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+/* hwrm_nvm_flush_output (size:128b/16B) */
+struct hwrm_nvm_flush_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_flush_cmd_err (size:64b/8B) */
+struct hwrm_nvm_flush_cmd_err {
+ /*
+ * command specific error codes that goes to
+ * the cmd_err field in Common HWRM Error Response.
+ */
+ uint8_t code;
+ /* Unknown error */
+ #define HWRM_NVM_FLUSH_CMD_ERR_CODE_UNKNOWN UINT32_C(0x0)
+ /* flush could not be performed */
+ #define HWRM_NVM_FLUSH_CMD_ERR_CODE_FAIL UINT32_C(0x1)
+ #define HWRM_NVM_FLUSH_CMD_ERR_CODE_LAST \
+ HWRM_NVM_FLUSH_CMD_ERR_CODE_FAIL
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/*************************
+ * hwrm_nvm_get_variable *
+ *************************/
+
+
+/* hwrm_nvm_get_variable_input (size:320b/40B) */
+struct hwrm_nvm_get_variable_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This is the host address where
+ * nvm variable will be stored
+ */
+ uint64_t dest_data_addr;
+ /* size of data in bits */
+ uint16_t data_len;
+ /* nvm cfg option number */
+ uint16_t option_num;
+ /* reserved. */
+ #define HWRM_NVM_GET_VARIABLE_INPUT_OPTION_NUM_RSVD_0 UINT32_C(0x0)
+ /* reserved. */
+ #define HWRM_NVM_GET_VARIABLE_INPUT_OPTION_NUM_RSVD_FFFF \
+ UINT32_C(0xffff)
+ #define HWRM_NVM_GET_VARIABLE_INPUT_OPTION_NUM_LAST \
+ HWRM_NVM_GET_VARIABLE_INPUT_OPTION_NUM_RSVD_FFFF
+ /*
+ * Number of dimensions for this nvm configuration variable.
+ * This value indicates how many of the indexN values to use.
+ * A value of 0 means that none of the indexN values are valid.
+ * A value of 1 requires at index0 is valued, a value of 2
+ * requires that index0 and index1 are valid, and so forth
+ */
+ uint16_t dimensions;
+ /* index for the 1st dimensions */
+ uint16_t index_0;
+ /* index for the 2nd dimensions */
+ uint16_t index_1;
+ /* index for the 3rd dimensions */
+ uint16_t index_2;
+ /* index for the 4th dimensions */
+ uint16_t index_3;
+ uint8_t flags;
+ /*
+ * When this bit is set to 1, the factory default value will be returned,
+ * 0 returns the operational value.
+ */
+ #define HWRM_NVM_GET_VARIABLE_INPUT_FLAGS_FACTORY_DFLT \
+ UINT32_C(0x1)
+ uint8_t unused_0;
+} __attribute__((packed));
+
+/* hwrm_nvm_get_variable_output (size:128b/16B) */
+struct hwrm_nvm_get_variable_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ /* size of data of the actual variable retrieved in bits */
+ uint16_t data_len;
+ /*
+ * option_num is the option number for the data retrieved. It is possible in the
+ * future that the option number returned would be different than requested. This
+ * condition could occur if an option is deprecated and a new option id is defined
+ * with similar characteristics, but has a slightly different definition. This
+ * also makes it convenient for the caller to identify the variable result with
+ * the option id from the response.
+ */
+ uint16_t option_num;
+ /* reserved. */
+ #define HWRM_NVM_GET_VARIABLE_OUTPUT_OPTION_NUM_RSVD_0 UINT32_C(0x0)
+ /* reserved. */
+ #define HWRM_NVM_GET_VARIABLE_OUTPUT_OPTION_NUM_RSVD_FFFF \
+ UINT32_C(0xffff)
+ #define HWRM_NVM_GET_VARIABLE_OUTPUT_OPTION_NUM_LAST \
+ HWRM_NVM_GET_VARIABLE_OUTPUT_OPTION_NUM_RSVD_FFFF
+ uint8_t unused_0[3];
+ /*
+ * 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_nvm_get_variable_cmd_err (size:64b/8B) */
+struct hwrm_nvm_get_variable_cmd_err {
+ /*
+ * command specific error codes that goes to
+ * the cmd_err field in Common HWRM Error Response.
+ */
+ uint8_t code;
+ /* Unknown error */
+ #define HWRM_NVM_GET_VARIABLE_CMD_ERR_CODE_UNKNOWN UINT32_C(0x0)
+ /* variable does not exist */
+ #define HWRM_NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST UINT32_C(0x1)
+ /* configuration is corrupted and the variable cannot be saved */
+ #define HWRM_NVM_GET_VARIABLE_CMD_ERR_CODE_CORRUPT_VAR UINT32_C(0x2)
+ /* length specified is too small */
+ #define HWRM_NVM_GET_VARIABLE_CMD_ERR_CODE_LEN_TOO_SHORT UINT32_C(0x3)
+ #define HWRM_NVM_GET_VARIABLE_CMD_ERR_CODE_LAST \
+ HWRM_NVM_GET_VARIABLE_CMD_ERR_CODE_LEN_TOO_SHORT
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/*************************
+ * hwrm_nvm_set_variable *
+ *************************/
+
+
+/* hwrm_nvm_set_variable_input (size:320b/40B) */
+struct hwrm_nvm_set_variable_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This is the host address where
+ * nvm variable will be copied from
+ */
+ uint64_t src_data_addr;
+ /* size of data in bits */
+ uint16_t data_len;
+ /* nvm cfg option number */
+ uint16_t option_num;
+ /* reserved. */
+ #define HWRM_NVM_SET_VARIABLE_INPUT_OPTION_NUM_RSVD_0 UINT32_C(0x0)
+ /* reserved. */
+ #define HWRM_NVM_SET_VARIABLE_INPUT_OPTION_NUM_RSVD_FFFF \
+ UINT32_C(0xffff)
+ #define HWRM_NVM_SET_VARIABLE_INPUT_OPTION_NUM_LAST \
+ HWRM_NVM_SET_VARIABLE_INPUT_OPTION_NUM_RSVD_FFFF
+ /*
+ * Number of dimensions for this nvm configuration variable.
+ * This value indicates how many of the indexN values to use.
+ * A value of 0 means that none of the indexN values are valid.
+ * A value of 1 requires at index0 is valued, a value of 2
+ * requires that index0 and index1 are valid, and so forth
+ */
+ uint16_t dimensions;
+ /* index for the 1st dimensions */
+ uint16_t index_0;
+ /* index for the 2nd dimensions */
+ uint16_t index_1;
+ /* index for the 3rd dimensions */
+ uint16_t index_2;
+ /* index for the 4th dimensions */
+ uint16_t index_3;
+ uint8_t flags;
+ /* When this bit is 1, flush internal cache after this write operation (see hwrm_nvm_flush command.) */
+ #define HWRM_NVM_SET_VARIABLE_INPUT_FLAGS_FORCE_FLUSH \
+ UINT32_C(0x1)
+ /* encryption method */
+ #define HWRM_NVM_SET_VARIABLE_INPUT_FLAGS_ENCRYPT_MODE_MASK \
+ UINT32_C(0xe)
+ #define HWRM_NVM_SET_VARIABLE_INPUT_FLAGS_ENCRYPT_MODE_SFT 1
+ /* No encryption. */
+ #define HWRM_NVM_SET_VARIABLE_INPUT_FLAGS_ENCRYPT_MODE_NONE \
+ (UINT32_C(0x0) << 1)
+ /* one-way encryption. */
+ #define HWRM_NVM_SET_VARIABLE_INPUT_FLAGS_ENCRYPT_MODE_HMAC_SHA1 \
+ (UINT32_C(0x1) << 1)
+ /* symmetric AES256 encryption. */
+ #define HWRM_NVM_SET_VARIABLE_INPUT_FLAGS_ENCRYPT_MODE_AES256 \
+ (UINT32_C(0x2) << 1)
+ /* SHA1 digest appended to plaintext contents, for authentication */
+ #define HWRM_NVM_SET_VARIABLE_INPUT_FLAGS_ENCRYPT_MODE_HMAC_SHA1_AUTH \
+ (UINT32_C(0x3) << 1)
+ #define HWRM_NVM_SET_VARIABLE_INPUT_FLAGS_ENCRYPT_MODE_LAST \
+ HWRM_NVM_SET_VARIABLE_INPUT_FLAGS_ENCRYPT_MODE_HMAC_SHA1_AUTH
+ uint8_t unused_0;
+} __attribute__((packed));
+
+/* hwrm_nvm_set_variable_output (size:128b/16B) */
+struct hwrm_nvm_set_variable_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t unused_0[7];
+ /*
+ * 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_nvm_set_variable_cmd_err (size:64b/8B) */
+struct hwrm_nvm_set_variable_cmd_err {
+ /*
+ * command specific error codes that goes to
+ * the cmd_err field in Common HWRM Error Response.
+ */
+ uint8_t code;
+ /* Unknown error */
+ #define HWRM_NVM_SET_VARIABLE_CMD_ERR_CODE_UNKNOWN UINT32_C(0x0)
+ /* variable does not exist */
+ #define HWRM_NVM_SET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST UINT32_C(0x1)
+ /* configuration is corrupted and the variable cannot be saved */
+ #define HWRM_NVM_SET_VARIABLE_CMD_ERR_CODE_CORRUPT_VAR UINT32_C(0x2)
+ #define HWRM_NVM_SET_VARIABLE_CMD_ERR_CODE_LAST \
+ HWRM_NVM_SET_VARIABLE_CMD_ERR_CODE_CORRUPT_VAR
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/****************************
+ * hwrm_nvm_validate_option *
+ ****************************/
+
+
+/* hwrm_nvm_validate_option_input (size:320b/40B) */
+struct hwrm_nvm_validate_option_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /*
+ * This is the host address where
+ * nvm variable will be copied from
+ */
+ uint64_t src_data_addr;
+ /* size of data in bits */
+ uint16_t data_len;
+ /* nvm cfg option number */
+ uint16_t option_num;
+ /* reserved. */
+ #define HWRM_NVM_VALIDATE_OPTION_INPUT_OPTION_NUM_RSVD_0 \
+ UINT32_C(0x0)
+ /* reserved. */
+ #define HWRM_NVM_VALIDATE_OPTION_INPUT_OPTION_NUM_RSVD_FFFF \
+ UINT32_C(0xffff)
+ #define HWRM_NVM_VALIDATE_OPTION_INPUT_OPTION_NUM_LAST \
+ HWRM_NVM_VALIDATE_OPTION_INPUT_OPTION_NUM_RSVD_FFFF
+ /*
+ * Number of dimensions for this nvm configuration variable.
+ * This value indicates how many of the indexN values to use.
+ * A value of 0 means that none of the indexN values are valid.
+ * A value of 1 requires at index0 is valued, a value of 2
+ * requires that index0 and index1 are valid, and so forth
+ */
+ uint16_t dimensions;
+ /* index for the 1st dimensions */
+ uint16_t index_0;
+ /* index for the 2nd dimensions */
+ uint16_t index_1;
+ /* index for the 3rd dimensions */
+ uint16_t index_2;
+ /* index for the 4th dimensions */
+ uint16_t index_3;
+ uint8_t unused_0[2];
+} __attribute__((packed));
+
+/* hwrm_nvm_validate_option_output (size:128b/16B) */
+struct hwrm_nvm_validate_option_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t result;
+ /* indicates that the value provided for the option is not matching with the saved data. */
+ #define HWRM_NVM_VALIDATE_OPTION_OUTPUT_RESULT_NOT_MATCH UINT32_C(0x0)
+ /* indicates that the value provided for the option is matching the saved data. */
+ #define HWRM_NVM_VALIDATE_OPTION_OUTPUT_RESULT_MATCH UINT32_C(0x1)
+ #define HWRM_NVM_VALIDATE_OPTION_OUTPUT_RESULT_LAST \
+ HWRM_NVM_VALIDATE_OPTION_OUTPUT_RESULT_MATCH
+ uint8_t unused_0[6];
+ /*
+ * 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_nvm_validate_option_cmd_err (size:64b/8B) */
+struct hwrm_nvm_validate_option_cmd_err {
+ /*
+ * command specific error codes that goes to
+ * the cmd_err field in Common HWRM Error Response.
+ */
+ uint8_t code;
+ /* Unknown error */
+ #define HWRM_NVM_VALIDATE_OPTION_CMD_ERR_CODE_UNKNOWN UINT32_C(0x0)
+ #define HWRM_NVM_VALIDATE_OPTION_CMD_ERR_CODE_LAST \
+ HWRM_NVM_VALIDATE_OPTION_CMD_ERR_CODE_UNKNOWN
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/*****************************
+ * hwrm_nvm_factory_defaults *
+ *****************************/
+
+
+/* hwrm_nvm_factory_defaults_input (size:192b/24B) */
+struct hwrm_nvm_factory_defaults_input {
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /*
+ * The completion ring to send the completion event on. This should
+ * be the NQ ID returned from the `nq_alloc` HWRM command.
+ */
+ uint16_t cmpl_ring;
+ /*
+ * The sequence ID is used by the driver for tracking multiple
+ * commands. This ID is treated as opaque data by the firmware and
+ * the value is returned in the `hwrm_resp_hdr` upon completion.
+ */
+ uint16_t seq_id;
+ /*
+ * The target ID of the command:
+ * * 0x0-0xFFF8 - The function ID
+ * * 0xFFF8-0xFFFE - Reserved for internal processors
+ * * 0xFFFF - HWRM
+ */
+ uint16_t target_id;
+ /*
+ * A physical address pointer pointing to a host buffer that the
+ * command's response data will be written. This can be either a host
+ * physical address (HPA) or a guest physical address (GPA) and must
+ * point to a physically contiguous block of memory.
+ */
+ uint64_t resp_addr;
+ /* mode is 8 b */
+ uint8_t mode;
+ /* If set to 1, it will trigger restoration of factory default settings */
+ #define HWRM_NVM_FACTORY_DEFAULTS_INPUT_MODE_RESTORE UINT32_C(0x0)
+ /* If set to 1, it will trigger creation of factory default settings */
+ #define HWRM_NVM_FACTORY_DEFAULTS_INPUT_MODE_CREATE UINT32_C(0x1)
+ #define HWRM_NVM_FACTORY_DEFAULTS_INPUT_MODE_LAST \
+ HWRM_NVM_FACTORY_DEFAULTS_INPUT_MODE_CREATE
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+/* hwrm_nvm_factory_defaults_output (size:128b/16B) */
+struct hwrm_nvm_factory_defaults_output {
+ /* The specific error status for the command. */
+ uint16_t error_code;
+ /* The HWRM command request type. */
+ uint16_t req_type;
+ /* The sequence ID from the original command. */
+ uint16_t seq_id;
+ /* The length of the response data in number of bytes. */
+ uint16_t resp_len;
+ uint8_t result;
+ /* factory defaults created successfully. */
+ #define HWRM_NVM_FACTORY_DEFAULTS_OUTPUT_RESULT_CREATE_OK \
+ UINT32_C(0x0)
+ /* factory defaults restored successfully. */
+ #define HWRM_NVM_FACTORY_DEFAULTS_OUTPUT_RESULT_RESTORE_OK \
+ UINT32_C(0x1)
+ /* factory defaults already created. */
+ #define HWRM_NVM_FACTORY_DEFAULTS_OUTPUT_RESULT_CREATE_ALREADY \
+ UINT32_C(0x2)
+ #define HWRM_NVM_FACTORY_DEFAULTS_OUTPUT_RESULT_LAST \
+ HWRM_NVM_FACTORY_DEFAULTS_OUTPUT_RESULT_CREATE_ALREADY
+ uint8_t unused_0[6];
+ /*
+ * 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_nvm_factory_defaults_cmd_err (size:64b/8B) */
+struct hwrm_nvm_factory_defaults_cmd_err {
+ /*
+ * command specific error codes that goes to
+ * the cmd_err field in Common HWRM Error Response.
+ */
+ uint8_t code;
+ /* Unknown error */
+ #define HWRM_NVM_FACTORY_DEFAULTS_CMD_ERR_CODE_UNKNOWN \
+ UINT32_C(0x0)
+ /* valid configuration not present to create defaults */
+ #define HWRM_NVM_FACTORY_DEFAULTS_CMD_ERR_CODE_NO_VALID_CFG \
+ UINT32_C(0x1)
+ /* No saved configuration present to restore, restore failed */
+ #define HWRM_NVM_FACTORY_DEFAULTS_CMD_ERR_CODE_NO_SAVED_CFG \
+ UINT32_C(0x2)
+ #define HWRM_NVM_FACTORY_DEFAULTS_CMD_ERR_CODE_LAST \
+ HWRM_NVM_FACTORY_DEFAULTS_CMD_ERR_CODE_NO_SAVED_CFG
+ uint8_t unused_0[7];
+} __attribute__((packed));
+
+#endif /* _HSI_STRUCT_DEF_DPDK_H_ */
diff --git a/src/spdk/dpdk/drivers/net/bnxt/meson.build b/src/spdk/dpdk/drivers/net/bnxt/meson.build
new file mode 100644
index 00000000..e130f271
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/meson.build
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Intel Corporation
+
+install_headers('rte_pmd_bnxt.h')
+version = 2
+sources = files('bnxt_cpr.c',
+ 'bnxt_ethdev.c',
+ 'bnxt_filter.c',
+ 'bnxt_flow.c',
+ 'bnxt_hwrm.c',
+ 'bnxt_irq.c',
+ 'bnxt_ring.c',
+ 'bnxt_rxq.c',
+ 'bnxt_rxr.c',
+ 'bnxt_stats.c',
+ 'bnxt_txq.c',
+ 'bnxt_txr.c',
+ 'bnxt_util.c',
+ 'bnxt_vnic.c',
+ 'rte_pmd_bnxt.c')
diff --git a/src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt.c b/src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt.c
new file mode 100644
index 00000000..c298de83
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -0,0 +1,811 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Broadcom
+ * All rights reserved.
+ */
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include <rte_dev.h>
+#include <rte_ethdev_driver.h>
+#include <rte_malloc.h>
+#include <rte_cycles.h>
+#include <rte_byteorder.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_vnic.h"
+#include "rte_pmd_bnxt.h"
+#include "hsi_struct_def_dpdk.h"
+
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg)
+{
+ struct rte_pmd_bnxt_mb_event_param ret_param;
+
+ ret_param.retval = RTE_PMD_BNXT_MB_EVENT_PROCEED;
+ ret_param.vf_id = vf_id;
+ ret_param.msg = msg;
+
+ _rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX,
+ &ret_param);
+
+ /* Default to approve */
+ if (ret_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED)
+ ret_param.retval = RTE_PMD_BNXT_MB_EVENT_NOOP_ACK;
+
+ return ret_param.retval == RTE_PMD_BNXT_MB_EVENT_NOOP_ACK ?
+ true : false;
+}
+
+int rte_pmd_bnxt_set_tx_loopback(uint16_t port, uint8_t on)
+{
+ struct rte_eth_dev *eth_dev;
+ struct bnxt *bp;
+ int rc;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ if (on > 1)
+ return -EINVAL;
+
+ eth_dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(eth_dev))
+ return -ENOTSUP;
+
+ bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to set Tx loopback on non-PF port %d!\n",
+ port);
+ return -ENOTSUP;
+ }
+
+ if (on)
+ bp->pf.evb_mode = BNXT_EVB_MODE_VEB;
+ else
+ bp->pf.evb_mode = BNXT_EVB_MODE_VEPA;
+
+ rc = bnxt_hwrm_pf_evb_mode(bp);
+
+ return rc;
+}
+
+static void
+rte_pmd_bnxt_set_all_queues_drop_en_cb(struct bnxt_vnic_info *vnic, void *onptr)
+{
+ uint8_t *on = onptr;
+ vnic->bd_stall = !(*on);
+}
+
+int rte_pmd_bnxt_set_all_queues_drop_en(uint16_t port, uint8_t on)
+{
+ struct rte_eth_dev *eth_dev;
+ struct bnxt *bp;
+ uint32_t i;
+ int rc = -EINVAL;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ if (on > 1)
+ return -EINVAL;
+
+ eth_dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(eth_dev))
+ return -ENOTSUP;
+
+ bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to set all queues drop on non-PF port!\n");
+ return -ENOTSUP;
+ }
+
+ if (bp->vnic_info == NULL)
+ return -ENODEV;
+
+ /* Stall PF */
+ for (i = 0; i < bp->nr_vnics; i++) {
+ bp->vnic_info[i].bd_stall = !on;
+ rc = bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[i]);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "Failed to update PF VNIC %d.\n", i);
+ return rc;
+ }
+ }
+
+ /* Stall all active VFs */
+ for (i = 0; i < bp->pf.active_vfs; i++) {
+ rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, i,
+ rte_pmd_bnxt_set_all_queues_drop_en_cb, &on,
+ bnxt_hwrm_vnic_cfg);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "Failed to update VF VNIC %d.\n", i);
+ break;
+ }
+ }
+
+ return rc;
+}
+
+int rte_pmd_bnxt_set_vf_mac_addr(uint16_t port, uint16_t vf,
+ struct ether_addr *mac_addr)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct bnxt *bp;
+ int rc;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (vf >= dev_info.max_vfs || mac_addr == NULL)
+ return -EINVAL;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to set VF %d mac address on non-PF port %d!\n",
+ vf, port);
+ return -ENOTSUP;
+ }
+
+ rc = bnxt_hwrm_func_vf_mac(bp, vf, (uint8_t *)mac_addr);
+
+ return rc;
+}
+
+int rte_pmd_bnxt_set_vf_rate_limit(uint16_t port, uint16_t vf,
+ uint16_t tx_rate, uint64_t q_msk)
+{
+ struct rte_eth_dev *eth_dev;
+ struct rte_eth_dev_info dev_info;
+ struct bnxt *bp;
+ uint16_t tot_rate = 0;
+ uint64_t idx;
+ int rc;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ eth_dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(eth_dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ if (!bp->pf.active_vfs)
+ return -EINVAL;
+
+ if (vf >= bp->pf.max_vfs)
+ return -EINVAL;
+
+ /* Add up the per queue BW and configure MAX BW of the VF */
+ for (idx = 0; idx < 64; idx++) {
+ if ((1ULL << idx) & q_msk)
+ tot_rate += tx_rate;
+ }
+
+ /* Requested BW can't be greater than link speed */
+ if (tot_rate > eth_dev->data->dev_link.link_speed) {
+ PMD_DRV_LOG(ERR, "Rate > Link speed. Set to %d\n", tot_rate);
+ return -EINVAL;
+ }
+
+ /* Requested BW already configured */
+ if (tot_rate == bp->pf.vf_info[vf].max_tx_rate)
+ return 0;
+
+ rc = bnxt_hwrm_func_bw_cfg(bp, vf, tot_rate,
+ HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW);
+
+ if (!rc)
+ bp->pf.vf_info[vf].max_tx_rate = tot_rate;
+
+ return rc;
+}
+
+int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf, uint8_t on)
+{
+ struct rte_eth_dev_info dev_info;
+ struct rte_eth_dev *dev;
+ uint32_t func_flags;
+ struct bnxt *bp;
+ int rc;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ if (on > 1)
+ return -EINVAL;
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to set mac spoof on non-PF port %d!\n", port);
+ return -EINVAL;
+ }
+
+ if (vf >= dev_info.max_vfs)
+ return -EINVAL;
+
+ /* Prev setting same as new setting. */
+ if (on == bp->pf.vf_info[vf].mac_spoof_en)
+ return 0;
+
+ func_flags = bp->pf.vf_info[vf].func_cfg_flags;
+ func_flags &= ~(HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE |
+ HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE);
+
+ if (on)
+ func_flags |=
+ HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE;
+ else
+ func_flags |=
+ HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
+
+ rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags);
+ if (!rc) {
+ bp->pf.vf_info[vf].mac_spoof_en = on;
+ bp->pf.vf_info[vf].func_cfg_flags = func_flags;
+ }
+
+ return rc;
+}
+
+int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf, uint8_t on)
+{
+ struct rte_eth_dev_info dev_info;
+ struct rte_eth_dev *dev;
+ struct bnxt *bp;
+ int rc;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ if (on > 1)
+ return -EINVAL;
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to set VLAN spoof on non-PF port %d!\n", port);
+ return -EINVAL;
+ }
+
+ if (vf >= dev_info.max_vfs)
+ return -EINVAL;
+
+ rc = bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(bp, vf, on);
+ if (!rc) {
+ bp->pf.vf_info[vf].vlan_spoof_en = on;
+ if (on) {
+ if (bnxt_hwrm_cfa_vlan_antispoof_cfg(bp,
+ bp->pf.first_vf_id + vf,
+ bp->pf.vf_info[vf].vlan_count,
+ bp->pf.vf_info[vf].vlan_as_table))
+ rc = -1;
+ }
+ } else {
+ PMD_DRV_LOG(ERR, "Failed to update VF VNIC %d.\n", vf);
+ }
+
+ return rc;
+}
+
+static void
+rte_pmd_bnxt_set_vf_vlan_stripq_cb(struct bnxt_vnic_info *vnic, void *onptr)
+{
+ uint8_t *on = onptr;
+ vnic->vlan_strip = *on;
+}
+
+int
+rte_pmd_bnxt_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct bnxt *bp;
+ int rc;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (vf >= dev_info.max_vfs)
+ return -EINVAL;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to set VF %d stripq on non-PF port %d!\n",
+ vf, port);
+ return -ENOTSUP;
+ }
+
+ rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
+ rte_pmd_bnxt_set_vf_vlan_stripq_cb, &on,
+ bnxt_hwrm_vnic_cfg);
+ if (rc)
+ PMD_DRV_LOG(ERR, "Failed to update VF VNIC %d.\n", vf);
+
+ return rc;
+}
+
+int rte_pmd_bnxt_set_vf_rxmode(uint16_t port, uint16_t vf,
+ uint16_t rx_mask, uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ uint16_t flag = 0;
+ struct bnxt *bp;
+ int rc;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (!bp->pf.vf_info)
+ return -EINVAL;
+
+ if (vf >= bp->pdev->max_vfs)
+ return -EINVAL;
+
+ if (rx_mask & ETH_VMDQ_ACCEPT_UNTAG) {
+ PMD_DRV_LOG(ERR, "Currently cannot toggle this setting\n");
+ return -ENOTSUP;
+ }
+
+ /* Is this really the correct mapping? VFd seems to think it is. */
+ if (rx_mask & ETH_VMDQ_ACCEPT_HASH_UC)
+ flag |= BNXT_VNIC_INFO_PROMISC;
+
+ if (rx_mask & ETH_VMDQ_ACCEPT_BROADCAST)
+ flag |= BNXT_VNIC_INFO_BCAST;
+ if (rx_mask & ETH_VMDQ_ACCEPT_MULTICAST)
+ flag |= BNXT_VNIC_INFO_ALLMULTI | BNXT_VNIC_INFO_MCAST;
+
+ if (on)
+ bp->pf.vf_info[vf].l2_rx_mask |= flag;
+ else
+ bp->pf.vf_info[vf].l2_rx_mask &= ~flag;
+
+ rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
+ vf_vnic_set_rxmask_cb,
+ &bp->pf.vf_info[vf].l2_rx_mask,
+ bnxt_set_rx_mask_no_vlan);
+ if (rc)
+ PMD_DRV_LOG(ERR, "bnxt_hwrm_func_vf_vnic_set_rxmask failed\n");
+
+ return rc;
+}
+
+static int bnxt_set_vf_table(struct bnxt *bp, uint16_t vf)
+{
+ int rc = 0;
+ int dflt_vnic;
+ struct bnxt_vnic_info vnic;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to set VLAN table on non-PF port!\n");
+ return -EINVAL;
+ }
+
+ if (vf >= bp->pdev->max_vfs)
+ return -EINVAL;
+
+ dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
+ if (dflt_vnic < 0) {
+ /* This simply indicates there's no driver loaded.
+ * This is not an error.
+ */
+ PMD_DRV_LOG(ERR, "Unable to get default VNIC for VF %d\n", vf);
+ } else {
+ memset(&vnic, 0, sizeof(vnic));
+ vnic.fw_vnic_id = dflt_vnic;
+ if (bnxt_hwrm_vnic_qcfg(bp, &vnic,
+ bp->pf.first_vf_id + vf) == 0) {
+ if (bnxt_hwrm_cfa_l2_set_rx_mask(bp, &vnic,
+ bp->pf.vf_info[vf].vlan_count,
+ bp->pf.vf_info[vf].vlan_table))
+ rc = -1;
+ } else {
+ rc = -1;
+ }
+ }
+
+ return rc;
+}
+
+int rte_pmd_bnxt_set_vf_vlan_filter(uint16_t port, uint16_t vlan,
+ uint64_t vf_mask, uint8_t vlan_on)
+{
+ struct bnxt_vlan_table_entry *ve;
+ struct bnxt_vlan_antispoof_table_entry *vase;
+ struct rte_eth_dev *dev;
+ struct bnxt *bp;
+ uint16_t cnt;
+ int rc = 0;
+ int i, j;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ bp = (struct bnxt *)dev->data->dev_private;
+ if (!bp->pf.vf_info)
+ return -EINVAL;
+
+ for (i = 0; vf_mask; i++, vf_mask >>= 1) {
+ cnt = bp->pf.vf_info[i].vlan_count;
+ if ((vf_mask & 1) == 0)
+ continue;
+
+ if (bp->pf.vf_info[i].vlan_table == NULL) {
+ rc = -1;
+ continue;
+ }
+ if (bp->pf.vf_info[i].vlan_as_table == NULL) {
+ rc = -1;
+ continue;
+ }
+ if (vlan_on) {
+ /* First, search for a duplicate... */
+ for (j = 0; j < cnt; j++) {
+ if (rte_be_to_cpu_16(
+ bp->pf.vf_info[i].vlan_table[j].vid) == vlan)
+ break;
+ }
+ if (j == cnt) {
+ /* Now check that there's space */
+ if (cnt == getpagesize() / sizeof(struct
+ bnxt_vlan_antispoof_table_entry)) {
+ PMD_DRV_LOG(ERR,
+ "VLAN anti-spoof table is full\n");
+ PMD_DRV_LOG(ERR,
+ "VF %d cannot add VLAN %u\n",
+ i, vlan);
+ rc = -1;
+ continue;
+ }
+
+ /* cnt is one less than vlan_count */
+ cnt = bp->pf.vf_info[i].vlan_count++;
+ /*
+ * And finally, add to the
+ * end of the table
+ */
+ vase = &bp->pf.vf_info[i].vlan_as_table[cnt];
+ // TODO: Hardcoded TPID
+ vase->tpid = rte_cpu_to_be_16(0x8100);
+ vase->vid = rte_cpu_to_be_16(vlan);
+ vase->mask = rte_cpu_to_be_16(0xfff);
+ ve = &bp->pf.vf_info[i].vlan_table[cnt];
+ /* TODO: Hardcoded TPID */
+ ve->tpid = rte_cpu_to_be_16(0x8100);
+ ve->vid = rte_cpu_to_be_16(vlan);
+ }
+ } else {
+ for (j = 0; j < cnt; j++) {
+ if (rte_be_to_cpu_16(
+ bp->pf.vf_info[i].vlan_table[j].vid) != vlan)
+ continue;
+ memmove(&bp->pf.vf_info[i].vlan_table[j],
+ &bp->pf.vf_info[i].vlan_table[j + 1],
+ getpagesize() - ((j + 1) *
+ sizeof(struct bnxt_vlan_table_entry)));
+ memmove(&bp->pf.vf_info[i].vlan_as_table[j],
+ &bp->pf.vf_info[i].vlan_as_table[j + 1],
+ getpagesize() - ((j + 1) * sizeof(struct
+ bnxt_vlan_antispoof_table_entry)));
+ j--;
+ cnt = --bp->pf.vf_info[i].vlan_count;
+ }
+ }
+ bnxt_set_vf_table(bp, i);
+ }
+
+ return rc;
+}
+
+int rte_pmd_bnxt_get_vf_stats(uint16_t port,
+ uint16_t vf_id,
+ struct rte_eth_stats *stats)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct bnxt *bp;
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (vf_id >= dev_info.max_vfs)
+ return -EINVAL;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to get VF %d stats on non-PF port %d!\n",
+ vf_id, port);
+ return -ENOTSUP;
+ }
+
+ return bnxt_hwrm_func_qstats(bp, bp->pf.first_vf_id + vf_id, stats);
+}
+
+int rte_pmd_bnxt_reset_vf_stats(uint16_t port,
+ uint16_t vf_id)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct bnxt *bp;
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (vf_id >= dev_info.max_vfs)
+ return -EINVAL;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to reset VF %d stats on non-PF port %d!\n",
+ vf_id, port);
+ return -ENOTSUP;
+ }
+
+ return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
+}
+
+int rte_pmd_bnxt_get_vf_rx_status(uint16_t port, uint16_t vf_id)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct bnxt *bp;
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (vf_id >= dev_info.max_vfs)
+ return -EINVAL;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to query VF %d RX stats on non-PF port %d!\n",
+ vf_id, port);
+ return -ENOTSUP;
+ }
+
+ return bnxt_vf_vnic_count(bp, vf_id);
+}
+
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint16_t port, uint16_t vf_id,
+ uint64_t *count)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct bnxt *bp;
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (vf_id >= dev_info.max_vfs)
+ return -EINVAL;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to query VF %d TX drops on non-PF port %d!\n",
+ vf_id, port);
+ return -ENOTSUP;
+ }
+
+ return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
+ count);
+}
+
+int rte_pmd_bnxt_mac_addr_add(uint16_t port, struct ether_addr *addr,
+ uint32_t vf_id)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct bnxt *bp;
+ struct bnxt_filter_info *filter;
+ struct bnxt_vnic_info vnic;
+ struct ether_addr dflt_mac;
+ int rc;
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (vf_id >= dev_info.max_vfs)
+ return -EINVAL;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to config VF %d MAC on non-PF port %d!\n",
+ vf_id, port);
+ return -ENOTSUP;
+ }
+
+ /* If the VF currently uses a random MAC, update default to this one */
+ if (bp->pf.vf_info[vf_id].random_mac) {
+ if (rte_pmd_bnxt_get_vf_rx_status(port, vf_id) <= 0)
+ bnxt_hwrm_func_vf_mac(bp, vf_id, (uint8_t *)addr);
+ }
+
+ /* query the default VNIC id used by the function */
+ rc = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf_id);
+ if (rc < 0)
+ goto exit;
+
+ memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+ vnic.fw_vnic_id = rte_le_to_cpu_16(rc);
+ rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf_id);
+ if (rc < 0)
+ goto exit;
+
+ STAILQ_FOREACH(filter, &bp->pf.vf_info[vf_id].filter, next) {
+ if (filter->flags ==
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX &&
+ filter->enables ==
+ (HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK) &&
+ memcmp(addr, filter->l2_addr, ETHER_ADDR_LEN) == 0) {
+ bnxt_hwrm_clear_l2_filter(bp, filter);
+ break;
+ }
+ }
+
+ if (filter == NULL)
+ filter = bnxt_alloc_vf_filter(bp, vf_id);
+
+ filter->fw_l2_filter_id = UINT64_MAX;
+ filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
+ filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
+ memcpy(filter->l2_addr, addr, ETHER_ADDR_LEN);
+ memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+
+ /* Do not add a filter for the default MAC */
+ if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf_id, &dflt_mac) ||
+ memcmp(filter->l2_addr, dflt_mac.addr_bytes, ETHER_ADDR_LEN))
+ rc = bnxt_hwrm_set_l2_filter(bp, vnic.fw_vnic_id, filter);
+
+exit:
+ return rc;
+}
+
+int
+rte_pmd_bnxt_set_vf_vlan_insert(uint16_t port, uint16_t vf,
+ uint16_t vlan_id)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct bnxt *bp;
+ int rc;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ if (!is_bnxt_supported(dev))
+ return -ENOTSUP;
+
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (vf >= dev_info.max_vfs)
+ return -EINVAL;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to set VF %d vlan insert on non-PF port %d!\n",
+ vf, port);
+ return -ENOTSUP;
+ }
+
+ bp->pf.vf_info[vf].dflt_vlan = vlan_id;
+ if (bnxt_hwrm_func_qcfg_current_vf_vlan(bp, vf) ==
+ bp->pf.vf_info[vf].dflt_vlan)
+ return 0;
+
+ rc = bnxt_hwrm_set_vf_vlan(bp, vf);
+
+ return rc;
+}
+
+int rte_pmd_bnxt_set_vf_persist_stats(uint16_t port, uint16_t vf, uint8_t on)
+{
+ struct rte_eth_dev_info dev_info;
+ struct rte_eth_dev *dev;
+ uint32_t func_flags;
+ struct bnxt *bp;
+ int rc;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ if (on > 1)
+ return -EINVAL;
+
+ dev = &rte_eth_devices[port];
+ rte_eth_dev_info_get(port, &dev_info);
+ bp = (struct bnxt *)dev->data->dev_private;
+
+ if (!BNXT_PF(bp)) {
+ PMD_DRV_LOG(ERR,
+ "Attempt to set persist stats on non-PF port %d!\n",
+ port);
+ return -EINVAL;
+ }
+
+ if (vf >= dev_info.max_vfs)
+ return -EINVAL;
+
+ /* Prev setting same as new setting. */
+ if (on == bp->pf.vf_info[vf].persist_stats)
+ return 0;
+
+ func_flags = bp->pf.vf_info[vf].func_cfg_flags;
+
+ if (on)
+ func_flags |=
+ HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC;
+ else
+ func_flags &=
+ ~HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC;
+
+ rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags);
+ if (!rc) {
+ bp->pf.vf_info[vf].persist_stats = on;
+ bp->pf.vf_info[vf].func_cfg_flags = func_flags;
+ }
+
+ return rc;
+}
diff --git a/src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt.h b/src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt.h
new file mode 100644
index 00000000..68fbe34d
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -0,0 +1,326 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _PMD_BNXT_H_
+#define _PMD_BNXT_H_
+
+#include <rte_ethdev_driver.h>
+
+/*
+ * Response sent back to the caller after callback
+ */
+enum rte_pmd_bnxt_mb_event_rsp {
+ RTE_PMD_BNXT_MB_EVENT_NOOP_ACK, /**< skip mbox request and ACK */
+ RTE_PMD_BNXT_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+ RTE_PMD_BNXT_MB_EVENT_PROCEED, /**< proceed with mbox request */
+ RTE_PMD_BNXT_MB_EVENT_MAX /**< max value of this enum */
+};
+
+/* mailbox message types */
+#define BNXT_VF_RESET 0x01 /* VF requests reset */
+#define BNXT_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */
+#define BNXT_VF_SET_VLAN 0x03 /* VF requests PF to set VLAN */
+#define BNXT_VF_SET_MTU 0x04 /* VF requests PF to set MTU */
+#define BNXT_VF_SET_MRU 0x05 /* VF requests PF to set MRU */
+
+/*
+ * Data sent to the caller when the callback is executed.
+ */
+struct rte_pmd_bnxt_mb_event_param {
+ uint16_t vf_id; /* Virtual Function number */
+ int retval; /* return value */
+ void *msg; /* pointer to message */
+};
+
+/**
+ * Enable/Disable VF MAC anti spoof
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF id.
+ * @param on
+ * 1 - Enable VF MAC anti spoof.
+ * 0 - Disable VF MAC anti spoof.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF id.
+ * @param mac_addr
+ * VF MAC address.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int rte_pmd_bnxt_set_vf_mac_addr(uint16_t port, uint16_t vf,
+ struct ether_addr *mac_addr);
+
+/**
+ * Enable/Disable vf vlan strip for all queues in a pool
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * ID specifying VF.
+ * @param on
+ * 1 - Enable VF's vlan strip on RX queues.
+ * 0 - Disable VF's vlan strip on RX queues.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support this feature.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_bnxt_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * ID specifying VF.
+ * @param vlan_id
+ * 0 - Disable VF's vlan insert.
+ * n - Enable; n is inserted as the vlan id.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_bnxt_set_vf_vlan_insert(uint16_t port, uint16_t vf,
+ uint16_t vlan_id);
+
+/**
+ * Enable/Disable hardware VF VLAN filtering by an Ethernet device of
+ * received VLAN packets tagged with a given VLAN Tag Identifier.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vlan
+ * The VLAN Tag Identifier whose filtering must be enabled or disabled.
+ * @param vf_mask
+ * Bitmap listing which VFs participate in the VLAN filtering.
+ * @param vlan_on
+ * 1 - Enable VFs VLAN filtering.
+ * 0 - Disable VFs VLAN filtering.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_vlan_filter(uint16_t port, uint16_t vlan,
+ uint64_t vf_mask, uint8_t vlan_on);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param on
+ * 1 - Enable tx loopback.
+ * 0 - Disable tx loopback.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_tx_loopback(uint16_t port, uint8_t on);
+
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param on
+ * 1 - set the queue drop enable bit for all pools.
+ * 0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_all_queues_drop_en(uint16_t port, uint8_t on);
+
+/**
+ * Set the VF rate limit.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF id.
+ * @param tx_rate
+ * Tx rate for the VF
+ * @param q_msk
+ * Mask of the Tx queue
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int rte_pmd_bnxt_set_vf_rate_limit(uint16_t port, uint16_t vf,
+ uint16_t tx_rate, uint64_t q_msk);
+
+/**
+ * Get VF's statistics
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf_id
+ * VF on which to get.
+ * @param stats
+ * A pointer to a structure of type *rte_eth_stats* to be filled with
+ * the values of device counters supported statistics:
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+
+int rte_pmd_bnxt_get_vf_stats(uint16_t port,
+ uint16_t vf_id,
+ struct rte_eth_stats *stats);
+
+/**
+ * Clear VF's statistics
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf_id
+ * VF on which to get.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_reset_vf_stats(uint16_t port,
+ uint16_t vf_id);
+
+/**
+ * Enable/Disable VF VLAN anti spoof
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF id.
+ * @param on
+ * 1 - Enable VF VLAN anti spoof.
+ * 0 - Disable VF VLAN anti spoof.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Set RX L2 Filtering mode of a VF of an Ethernet device.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF id.
+ * @param rx_mask
+ * The RX mode mask
+ * @param on
+ * 1 - Enable a VF RX mode.
+ * 0 - Disable a VF RX mode.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_rxmode(uint16_t port, uint16_t vf,
+ uint16_t rx_mask, uint8_t on);
+
+/**
+ * Returns the number of default RX queues on a VF
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF id.
+ * @return
+ * - Non-negative value - Number of default RX queues
+ * - (-EINVAL) if bad parameter.
+ * - (-ENOTSUP) if on a function without VFs
+ * - (-ENOMEM) on an allocation failure
+ * - (-1) firmware interface error
+ */
+int rte_pmd_bnxt_get_vf_rx_status(uint16_t port, uint16_t vf_id);
+
+/**
+ * Queries the TX drop counter for the function
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf_id
+ * VF on which to get.
+ * @param count
+ * Pointer to a uint64_t that will be populated with the counter value.
+ * @return
+ * - Positive Non-zero value - Error code from HWRM
+ * - (-EINVAL) invalid vf_id specified.
+ * - (-ENOTSUP) Ethernet device is not a PF
+ */
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint16_t port, uint16_t vf_id,
+ uint64_t *count);
+
+/**
+ * Programs the MAC address for the function specified
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param mac_addr
+ * The MAC address to be programmed in the filter.
+ * @param vf_id
+ * VF on which to get.
+ * @return
+ * - Positive Non-zero value - Error code from HWRM
+ * - (-EINVAL) invalid vf_id specified.
+ * - (-ENOTSUP) Ethernet device is not a PF
+ * - (-ENOMEM) on an allocation failure
+ */
+int rte_pmd_bnxt_mac_addr_add(uint16_t port, struct ether_addr *mac_addr,
+ uint32_t vf_id);
+
+/**
+ * Enable/Disable VF statistics retention
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF id.
+ * @param on
+ * 1 - Prevent VF statistics from automatically resetting
+ * 0 - Allow VF statistics to automatically reset
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_persist_stats(uint16_t port, uint16_t vf, uint8_t on);
+#endif /* _PMD_BNXT_H_ */
diff --git a/src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt_version.map b/src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt_version.map
new file mode 100644
index 00000000..4750d40a
--- /dev/null
+++ b/src/spdk/dpdk/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -0,0 +1,22 @@
+DPDK_17.08 {
+ global:
+
+ rte_pmd_bnxt_get_vf_rx_status;
+ rte_pmd_bnxt_get_vf_stats;
+ rte_pmd_bnxt_get_vf_tx_drop_count;
+ rte_pmd_bnxt_mac_addr_add;
+ rte_pmd_bnxt_reset_vf_stats;
+ rte_pmd_bnxt_set_all_queues_drop_en;
+ rte_pmd_bnxt_set_tx_loopback;
+ rte_pmd_bnxt_set_vf_mac_addr;
+ rte_pmd_bnxt_set_vf_mac_anti_spoof;
+ rte_pmd_bnxt_set_vf_rate_limit;
+ rte_pmd_bnxt_set_vf_rxmode;
+ rte_pmd_bnxt_set_vf_vlan_anti_spoof;
+ rte_pmd_bnxt_set_vf_vlan_filter;
+ rte_pmd_bnxt_set_vf_vlan_insert;
+ rte_pmd_bnxt_set_vf_vlan_stripq;
+ rte_pmd_bnxt_set_vf_persist_stats;
+
+ local: *;
+};