common/sfc_efx/base: do not validate MAE action COUNT order
[dpdk.git] / drivers / common / sfc_efx / base / efx.h
index 406e96c..24e1314 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  *
- * Copyright(c) 2019-2020 Xilinx, Inc.
+ * Copyright(c) 2019-2021 Xilinx, Inc.
  * Copyright(c) 2006-2019 Solarflare Communications Inc.
  */
 
@@ -1593,6 +1593,8 @@ typedef struct efx_nic_cfg_s {
        uint32_t                enc_mac_stats_nstats;
        boolean_t               enc_fec_counters;
        boolean_t               enc_hlb_counters;
+       /* NIC support for Match-Action Engine (MAE). */
+       boolean_t               enc_mae_supported;
        /* Firmware support for "FLAG" and "MARK" filter actions */
        boolean_t               enc_filter_action_flag_supported;
        boolean_t               enc_filter_action_mark_supported;
@@ -1601,11 +1603,13 @@ typedef struct efx_nic_cfg_s {
        uint32_t                enc_assigned_port;
 } efx_nic_cfg_t;
 
+#define        EFX_PCI_VF_INVALID 0xffff
+
 #define        EFX_VPORT_PCI_FUNCTION_IS_PF(configp) \
-       ((configp)->evc_function == 0xffff)
+       ((configp)->evc_function == EFX_PCI_VF_INVALID)
 
-#define        EFX_PCI_FUNCTION_IS_PF(_encp)   ((_encp)->enc_vf == 0xffff)
-#define        EFX_PCI_FUNCTION_IS_VF(_encp)   ((_encp)->enc_vf != 0xffff)
+#define        EFX_PCI_FUNCTION_IS_PF(_encp)   ((_encp)->enc_vf == EFX_PCI_VF_INVALID)
+#define        EFX_PCI_FUNCTION_IS_VF(_encp)   ((_encp)->enc_vf != EFX_PCI_VF_INVALID)
 
 #define        EFX_PCI_FUNCTION(_encp) \
        (EFX_PCI_FUNCTION_IS_PF(_encp) ? (_encp)->enc_pf : (_encp)->enc_vf)
@@ -1643,6 +1647,22 @@ efx_nic_get_fw_version(
        __in                    efx_nic_t *enp,
        __out                   efx_nic_fw_info_t *enfip);
 
+#define        EFX_NIC_BOARD_INFO_SERIAL_LEN   (64)
+#define        EFX_NIC_BOARD_INFO_NAME_LEN     (16)
+
+typedef struct efx_nic_board_info_s {
+       /* The following two fields are NUL-terminated ASCII strings. */
+       char                    enbi_serial[EFX_NIC_BOARD_INFO_SERIAL_LEN];
+       char                    enbi_name[EFX_NIC_BOARD_INFO_NAME_LEN];
+       uint32_t                enbi_revision;
+} efx_nic_board_info_t;
+
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_nic_get_board_info(
+       __in            efx_nic_t *enp,
+       __out           efx_nic_board_info_t *board_infop);
+
 /* Driver resource limits (minimum required/maximum usable). */
 typedef struct efx_drv_limits_s {
        uint32_t        edl_min_evq_count;
@@ -2313,6 +2333,19 @@ efx_ev_qcreate(
        __in            uint32_t flags,
        __deref_out     efx_evq_t **eepp);
 
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_ev_qcreate_irq(
+       __in            efx_nic_t *enp,
+       __in            unsigned int index,
+       __in            efsys_mem_t *esmp,
+       __in            size_t ndescs,
+       __in            uint32_t id,
+       __in            uint32_t us,
+       __in            uint32_t flags,
+       __in            uint32_t irq,
+       __deref_out     efx_evq_t **eepp);
+
 LIBEFX_API
 extern         void
 efx_ev_qpost(
@@ -2892,6 +2925,7 @@ typedef enum efx_rx_prefix_field_e {
        EFX_RX_PREFIX_FIELD_USER_MARK_VALID,
        EFX_RX_PREFIX_FIELD_CSUM_FRAME,
        EFX_RX_PREFIX_FIELD_INGRESS_VPORT,
+       EFX_RX_PREFIX_FIELD_INGRESS_MPORT = EFX_RX_PREFIX_FIELD_INGRESS_VPORT,
        EFX_RX_PREFIX_NFIELDS
 } efx_rx_prefix_field_t;
 
@@ -2920,6 +2954,18 @@ typedef struct efx_rx_prefix_layout_s {
        efx_rx_prefix_field_info_t      erpl_fields[EFX_RX_PREFIX_NFIELDS];
 } efx_rx_prefix_layout_t;
 
+/*
+ * Helper function to find out a bit mask of wanted but not available
+ * Rx prefix fields.
+ *
+ * A field is considered as not available if any parameter mismatch.
+ */
+LIBEFX_API
+extern __checkReturn   uint32_t
+efx_rx_prefix_layout_check(
+       __in            const efx_rx_prefix_layout_t *available,
+       __in            const efx_rx_prefix_layout_t *wanted);
+
 LIBEFX_API
 extern __checkReturn   efx_rc_t
 efx_rx_prefix_get_layout(
@@ -2953,6 +2999,14 @@ typedef enum efx_rxq_type_e {
  * the driver.
  */
 #define        EFX_RXQ_FLAG_RSS_HASH           0x4
+/*
+ * Request ingress mport field in the Rx prefix of a queue.
+ */
+#define        EFX_RXQ_FLAG_INGRESS_MPORT      0x8
+/*
+ * Request user mark field in the Rx prefix of a queue.
+ */
+#define        EFX_RXQ_FLAG_USER_MARK          0x10
 
 LIBEFX_API
 extern __checkReturn   efx_rc_t
@@ -3857,7 +3911,7 @@ typedef enum efx_vport_type_e {
 #define                EFX_VPORT_ID_INVALID    0
 
 typedef struct efx_vport_config_s {
-       /* Either VF index or 0xffff for PF */
+       /* Either VF index or EFX_PCI_VF_INVALID for PF */
        uint16_t        evc_function;
        /* VLAN ID of the associated function */
        uint16_t        evc_vid;
@@ -4022,6 +4076,625 @@ efx_proxy_auth_privilege_modify(
 
 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
 
+#if EFSYS_OPT_MAE
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_init(
+       __in                            efx_nic_t *enp);
+
+LIBEFX_API
+extern                                 void
+efx_mae_fini(
+       __in                            efx_nic_t *enp);
+
+typedef struct efx_mae_limits_s {
+       uint32_t                        eml_max_n_action_prios;
+       uint32_t                        eml_max_n_outer_prios;
+       uint32_t                        eml_encap_types_supported;
+       uint32_t                        eml_encap_header_size_limit;
+       uint32_t                        eml_max_n_counters;
+} efx_mae_limits_t;
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_get_limits(
+       __in                            efx_nic_t *enp,
+       __out                           efx_mae_limits_t *emlp);
+
+typedef enum efx_mae_rule_type_e {
+       EFX_MAE_RULE_ACTION = 0,
+       EFX_MAE_RULE_OUTER,
+
+       EFX_MAE_RULE_NTYPES
+} efx_mae_rule_type_t;
+
+typedef struct efx_mae_match_spec_s    efx_mae_match_spec_t;
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_match_spec_init(
+       __in                            efx_nic_t *enp,
+       __in                            efx_mae_rule_type_t type,
+       __in                            uint32_t prio,
+       __out                           efx_mae_match_spec_t **specp);
+
+LIBEFX_API
+extern                                 void
+efx_mae_match_spec_fini(
+       __in                            efx_nic_t *enp,
+       __in                            efx_mae_match_spec_t *spec);
+
+typedef enum efx_mae_field_id_e {
+       /*
+        * Fields which can be set by efx_mae_match_spec_field_set()
+        * or by using dedicated field-specific helper APIs.
+        */
+       EFX_MAE_FIELD_INGRESS_MPORT_SELECTOR = 0,
+       EFX_MAE_FIELD_ETHER_TYPE_BE,
+       EFX_MAE_FIELD_ETH_SADDR_BE,
+       EFX_MAE_FIELD_ETH_DADDR_BE,
+       EFX_MAE_FIELD_VLAN0_TCI_BE,
+       EFX_MAE_FIELD_VLAN0_PROTO_BE,
+       EFX_MAE_FIELD_VLAN1_TCI_BE,
+       EFX_MAE_FIELD_VLAN1_PROTO_BE,
+       EFX_MAE_FIELD_SRC_IP4_BE,
+       EFX_MAE_FIELD_DST_IP4_BE,
+       EFX_MAE_FIELD_IP_PROTO,
+       EFX_MAE_FIELD_IP_TOS,
+       EFX_MAE_FIELD_IP_TTL,
+       EFX_MAE_FIELD_SRC_IP6_BE,
+       EFX_MAE_FIELD_DST_IP6_BE,
+       EFX_MAE_FIELD_L4_SPORT_BE,
+       EFX_MAE_FIELD_L4_DPORT_BE,
+       EFX_MAE_FIELD_TCP_FLAGS_BE,
+       EFX_MAE_FIELD_ENC_ETHER_TYPE_BE,
+       EFX_MAE_FIELD_ENC_ETH_SADDR_BE,
+       EFX_MAE_FIELD_ENC_ETH_DADDR_BE,
+       EFX_MAE_FIELD_ENC_VLAN0_TCI_BE,
+       EFX_MAE_FIELD_ENC_VLAN0_PROTO_BE,
+       EFX_MAE_FIELD_ENC_VLAN1_TCI_BE,
+       EFX_MAE_FIELD_ENC_VLAN1_PROTO_BE,
+       EFX_MAE_FIELD_ENC_SRC_IP4_BE,
+       EFX_MAE_FIELD_ENC_DST_IP4_BE,
+       EFX_MAE_FIELD_ENC_IP_PROTO,
+       EFX_MAE_FIELD_ENC_IP_TOS,
+       EFX_MAE_FIELD_ENC_IP_TTL,
+       EFX_MAE_FIELD_ENC_SRC_IP6_BE,
+       EFX_MAE_FIELD_ENC_DST_IP6_BE,
+       EFX_MAE_FIELD_ENC_L4_SPORT_BE,
+       EFX_MAE_FIELD_ENC_L4_DPORT_BE,
+       EFX_MAE_FIELD_ENC_VNET_ID_BE,
+       EFX_MAE_FIELD_OUTER_RULE_ID,
+
+       /* Single bits which can be set by efx_mae_match_spec_bit_set(). */
+       EFX_MAE_FIELD_HAS_OVLAN,
+       EFX_MAE_FIELD_HAS_IVLAN,
+       EFX_MAE_FIELD_ENC_HAS_OVLAN,
+       EFX_MAE_FIELD_ENC_HAS_IVLAN,
+
+       EFX_MAE_FIELD_NIDS
+} efx_mae_field_id_t;
+
+/* MPORT selector. Used to refer to MPORTs in match/action rules. */
+typedef struct efx_mport_sel_s {
+       uint32_t sel;
+} efx_mport_sel_t;
+
+#define        EFX_MPORT_NULL                  (0U)
+
+/*
+ * Get MPORT selector of a physical port.
+ *
+ * The resulting MPORT selector is opaque to the caller and can be
+ * passed as an argument to efx_mae_match_spec_mport_set()
+ * and efx_mae_action_set_populate_deliver().
+ */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_mport_by_phy_port(
+       __in                            uint32_t phy_port,
+       __out                           efx_mport_sel_t *mportp);
+
+/*
+ * Get MPORT selector of a PCIe function.
+ *
+ * The resulting MPORT selector is opaque to the caller and can be
+ * passed as an argument to efx_mae_match_spec_mport_set()
+ * and efx_mae_action_set_populate_deliver().
+ */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_mport_by_pcie_function(
+       __in                            uint32_t pf,
+       __in                            uint32_t vf,
+       __out                           efx_mport_sel_t *mportp);
+
+/*
+ * Fields which have BE postfix in their named constants are expected
+ * to be passed by callers in big-endian byte order. They will appear
+ * in the MCDI buffer, which is a part of the match specification, in
+ * the very same byte order, that is, no conversion will be performed.
+ *
+ * Fields which don't have BE postfix in their named constants are in
+ * host byte order. MCDI expects them to be little-endian, so the API
+ * will take care to carry out conversion to little-endian byte order.
+ * At the moment, the only field in host byte order is MPORT selector.
+ */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_match_spec_field_set(
+       __in                            efx_mae_match_spec_t *spec,
+       __in                            efx_mae_field_id_t field_id,
+       __in                            size_t value_size,
+       __in_bcount(value_size)         const uint8_t *value,
+       __in                            size_t mask_size,
+       __in_bcount(mask_size)          const uint8_t *mask);
+
+/* The corresponding mask will be set to B_TRUE. */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_match_spec_bit_set(
+       __in                            efx_mae_match_spec_t *spec,
+       __in                            efx_mae_field_id_t field_id,
+       __in                            boolean_t value);
+
+/* If the mask argument is NULL, the API will use full mask by default. */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_match_spec_mport_set(
+       __in                            efx_mae_match_spec_t *spec,
+       __in                            const efx_mport_sel_t *valuep,
+       __in_opt                        const efx_mport_sel_t *maskp);
+
+LIBEFX_API
+extern __checkReturn                   boolean_t
+efx_mae_match_specs_equal(
+       __in                            const efx_mae_match_spec_t *left,
+       __in                            const efx_mae_match_spec_t *right);
+
+/*
+ * Make sure that match fields known by EFX have proper masks set
+ * in the match specification as per requirements of SF-122526-TC.
+ *
+ * In the case efx_mae_field_id_t lacks named identifiers for any
+ * fields which the FW maintains with support status MATCH_ALWAYS,
+ * the validation result may not be accurate.
+ */
+LIBEFX_API
+extern __checkReturn                   boolean_t
+efx_mae_match_spec_is_valid(
+       __in                            efx_nic_t *enp,
+       __in                            const efx_mae_match_spec_t *spec);
+
+typedef struct efx_mae_actions_s efx_mae_actions_t;
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_spec_init(
+       __in                            efx_nic_t *enp,
+       __out                           efx_mae_actions_t **specp);
+
+LIBEFX_API
+extern                                 void
+efx_mae_action_set_spec_fini(
+       __in                            efx_nic_t *enp,
+       __in                            efx_mae_actions_t *spec);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_decap(
+       __in                            efx_mae_actions_t *spec);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_vlan_pop(
+       __in                            efx_mae_actions_t *spec);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_vlan_push(
+       __in                            efx_mae_actions_t *spec,
+       __in                            uint16_t tpid_be,
+       __in                            uint16_t tci_be);
+
+/*
+ * Use efx_mae_action_set_fill_in_eh_id() to set ID of the allocated
+ * encap. header in the specification prior to action set allocation.
+ */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_encap(
+       __in                            efx_mae_actions_t *spec);
+
+/*
+ * Use efx_mae_action_set_fill_in_counter_id() to set ID of a counter
+ * in the specification prior to action set allocation.
+ *
+ * NOTICE: the HW will conduct action COUNT after actions DECAP,
+ * VLAN_POP, VLAN_PUSH (if any) have been applied to the packet,
+ * but, as a workaround, this order is not validated by the API.
+ *
+ * The workaround helps to unblock DPDK + Open vSwitch use case.
+ * In Open vSwitch, this action is always the first to be added,
+ * in particular, it's known to be inserted before action DECAP,
+ * so enforcing the right order here would cause runtime errors.
+ * The existing behaviour in Open vSwitch is unlikely to change
+ * any time soon, and the workaround is a good solution because
+ * in fact the real COUNT order is a don't care to Open vSwitch.
+ */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_count(
+       __in                            efx_mae_actions_t *spec);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_flag(
+       __in                            efx_mae_actions_t *spec);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_mark(
+       __in                            efx_mae_actions_t *spec,
+       __in                            uint32_t mark_value);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_deliver(
+       __in                            efx_mae_actions_t *spec,
+       __in                            const efx_mport_sel_t *mportp);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_populate_drop(
+       __in                            efx_mae_actions_t *spec);
+
+LIBEFX_API
+extern __checkReturn                   boolean_t
+efx_mae_action_set_specs_equal(
+       __in                            const efx_mae_actions_t *left,
+       __in                            const efx_mae_actions_t *right);
+
+/*
+ * Conduct a comparison to check whether two match specifications
+ * of equal rule type (action / outer) and priority would map to
+ * the very same rule class from the firmware's standpoint.
+ *
+ * For match specification fields that are not supported by firmware,
+ * the rule class only matches if the mask/value pairs for that field
+ * are equal. Clients should use efx_mae_match_spec_is_valid() before
+ * calling this API to detect usage of unsupported fields.
+ */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_match_specs_class_cmp(
+       __in                            efx_nic_t *enp,
+       __in                            const efx_mae_match_spec_t *left,
+       __in                            const efx_mae_match_spec_t *right,
+       __out                           boolean_t *have_same_classp);
+
+#define        EFX_MAE_RSRC_ID_INVALID UINT32_MAX
+
+/* Rule ID */
+typedef struct efx_mae_rule_id_s {
+       uint32_t id;
+} efx_mae_rule_id_t;
+
+LIBEFX_API
+extern __checkReturn           efx_rc_t
+efx_mae_outer_rule_insert(
+       __in                    efx_nic_t *enp,
+       __in                    const efx_mae_match_spec_t *spec,
+       __in                    efx_tunnel_protocol_t encap_type,
+       __out                   efx_mae_rule_id_t *or_idp);
+
+LIBEFX_API
+extern __checkReturn           efx_rc_t
+efx_mae_outer_rule_remove(
+       __in                    efx_nic_t *enp,
+       __in                    const efx_mae_rule_id_t *or_idp);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_match_spec_outer_rule_id_set(
+       __in                            efx_mae_match_spec_t *spec,
+       __in                            const efx_mae_rule_id_t *or_idp);
+
+/* Encap. header ID */
+typedef struct efx_mae_eh_id_s {
+       uint32_t id;
+} efx_mae_eh_id_t;
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_encap_header_alloc(
+       __in                            efx_nic_t *enp,
+       __in                            efx_tunnel_protocol_t encap_type,
+       __in_bcount(header_size)        uint8_t *header_data,
+       __in                            size_t header_size,
+       __out                           efx_mae_eh_id_t *eh_idp);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_encap_header_free(
+       __in                            efx_nic_t *enp,
+       __in                            const efx_mae_eh_id_t *eh_idp);
+
+/* See description before efx_mae_action_set_populate_encap(). */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_fill_in_eh_id(
+       __in                            efx_mae_actions_t *spec,
+       __in                            const efx_mae_eh_id_t *eh_idp);
+
+typedef struct efx_counter_s {
+       uint32_t id;
+} efx_counter_t;
+
+LIBEFX_API
+extern __checkReturn                   unsigned int
+efx_mae_action_set_get_nb_count(
+       __in                            const efx_mae_actions_t *spec);
+
+/* See description before efx_mae_action_set_populate_count(). */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_fill_in_counter_id(
+       __in                            efx_mae_actions_t *spec,
+       __in                            const efx_counter_t *counter_idp);
+
+/* Action set ID */
+typedef struct efx_mae_aset_id_s {
+       uint32_t id;
+} efx_mae_aset_id_t;
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_alloc(
+       __in                            efx_nic_t *enp,
+       __in                            const efx_mae_actions_t *spec,
+       __out                           efx_mae_aset_id_t *aset_idp);
+
+/*
+ * Generation count has two purposes:
+ *
+ * 1) Distinguish between counter packets that belong to freed counter
+ *    and the packets that belong to reallocated counter (with the same ID);
+ * 2) Make sure that all packets are received for a counter that was freed;
+ *
+ * API users should provide generation count out parameter in allocation
+ * function if counters can be reallocated and consistent counter values are
+ * required.
+ *
+ * API users that need consistent final counter values after counter
+ * deallocation or counter stream stop should provide the parameter in
+ * functions that free the counters and stop the counter stream.
+ */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_counters_alloc(
+       __in                            efx_nic_t *enp,
+       __in                            uint32_t n_counters,
+       __out                           uint32_t *n_allocatedp,
+       __out_ecount(n_counters)        efx_counter_t *countersp,
+       __out_opt                       uint32_t *gen_countp);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_counters_free(
+       __in                            efx_nic_t *enp,
+       __in                            uint32_t n_counters,
+       __out                           uint32_t *n_freedp,
+       __in_ecount(n_counters)         const efx_counter_t *countersp,
+       __out_opt                       uint32_t *gen_countp);
+
+/* When set, include counters with a value of zero */
+#define        EFX_MAE_COUNTERS_STREAM_IN_ZERO_SQUASH_DISABLE  (1U << 0)
+
+/*
+ * Set if credit-based flow control is used. In this case the driver
+ * must call efx_mae_counters_stream_give_credits() to notify the
+ * packetiser of descriptors written.
+ */
+#define        EFX_MAE_COUNTERS_STREAM_OUT_USES_CREDITS        (1U << 0)
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_counters_stream_start(
+       __in                            efx_nic_t *enp,
+       __in                            uint16_t rxq_id,
+       __in                            uint16_t packet_size,
+       __in                            uint32_t flags_in,
+       __out                           uint32_t *flags_out);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_counters_stream_stop(
+       __in                            efx_nic_t *enp,
+       __in                            uint16_t rxq_id,
+       __out_opt                       uint32_t *gen_countp);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_counters_stream_give_credits(
+       __in                            efx_nic_t *enp,
+       __in                            uint32_t n_credits);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_set_free(
+       __in                            efx_nic_t *enp,
+       __in                            const efx_mae_aset_id_t *aset_idp);
+
+/* Action set list ID */
+typedef struct efx_mae_aset_list_id_s {
+       uint32_t id;
+} efx_mae_aset_list_id_t;
+
+/*
+ * Either action set list ID or action set ID must be passed to this API,
+ * but not both.
+ */
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_rule_insert(
+       __in                            efx_nic_t *enp,
+       __in                            const efx_mae_match_spec_t *spec,
+       __in                            const efx_mae_aset_list_id_t *asl_idp,
+       __in                            const efx_mae_aset_id_t *as_idp,
+       __out                           efx_mae_rule_id_t *ar_idp);
+
+LIBEFX_API
+extern __checkReturn                   efx_rc_t
+efx_mae_action_rule_remove(
+       __in                            efx_nic_t *enp,
+       __in                            const efx_mae_rule_id_t *ar_idp);
+
+#endif /* EFSYS_OPT_MAE */
+
+#if EFSYS_OPT_VIRTIO
+
+/* A Virtio net device can have one or more pairs of Rx/Tx virtqueues
+ * while virtio block device has a single virtqueue,
+ * for further details refer section of 4.2.3 of SF-120734
+ */
+typedef enum efx_virtio_vq_type_e {
+       EFX_VIRTIO_VQ_TYPE_NET_RXQ,
+       EFX_VIRTIO_VQ_TYPE_NET_TXQ,
+       EFX_VIRTIO_VQ_TYPE_BLOCK,
+       EFX_VIRTIO_VQ_NTYPES
+} efx_virtio_vq_type_t;
+
+typedef struct efx_virtio_vq_dyncfg_s {
+       /*
+        * If queue is being created to be migrated then this
+        * should be the FINAL_PIDX value returned by MC_CMD_VIRTIO_FINI_QUEUE
+        * of the queue being migrated from. Otherwise, it should be zero.
+        */
+       uint32_t                evvd_vq_pidx;
+       /*
+        * If this queue is being created to be migrated then this
+        * should be the FINAL_CIDX value returned by MC_CMD_VIRTIO_FINI_QUEUE
+        * of the queue being migrated from. Otherwise, it should be zero.
+        */
+       uint32_t                evvd_vq_cidx;
+} efx_virtio_vq_dyncfg_t;
+
+/*
+ * Virtqueue size must be a power of 2, maximum size is 32768
+ * (see VIRTIO v1.1 section 2.6)
+ */
+#define EFX_VIRTIO_MAX_VQ_SIZE 0x8000
+
+typedef struct efx_virtio_vq_cfg_s {
+       unsigned int            evvc_vq_num;
+       efx_virtio_vq_type_t    evvc_type;
+       /*
+        * vDPA as VF : It is target VF number if queue is being created on VF.
+        * vDPA as PF : If queue to be created on PF then it should be
+        * EFX_PCI_VF_INVALID.
+        */
+       uint16_t                evvc_target_vf;
+       /*
+        * Maximum virtqueue size is EFX_VIRTIO_MAX_VQ_SIZE and
+        * virtqueue size 0 means the queue is unavailable.
+        */
+       uint32_t                evvc_vq_size;
+       efsys_dma_addr_t        evvc_desc_tbl_addr;
+       efsys_dma_addr_t        evvc_avail_ring_addr;
+       efsys_dma_addr_t        evvc_used_ring_addr;
+       /* MSIX vector number for the virtqueue or 0xFFFF if MSIX is not used */
+       uint16_t                evvc_msix_vector;
+       /*
+        * evvc_pas_id contains a PCIe address space identifier if the queue
+        * uses PASID.
+        */
+       boolean_t               evvc_use_pasid;
+       uint32_t                evvc_pas_id;
+       /* Negotiated virtio features to be applied to this virtqueue */
+       uint64_t                evcc_features;
+} efx_virtio_vq_cfg_t;
+
+typedef struct efx_virtio_vq_s efx_virtio_vq_t;
+
+typedef enum efx_virtio_device_type_e {
+       EFX_VIRTIO_DEVICE_TYPE_RESERVED,
+       EFX_VIRTIO_DEVICE_TYPE_NET,
+       EFX_VIRTIO_DEVICE_TYPE_BLOCK,
+       EFX_VIRTIO_DEVICE_NTYPES
+} efx_virtio_device_type_t;
+
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_virtio_init(
+       __in            efx_nic_t *enp);
+
+LIBEFX_API
+extern                 void
+efx_virtio_fini(
+       __in            efx_nic_t *enp);
+
+/*
+ * When virtio net driver in the guest sets VIRTIO_CONFIG_STATUS_DRIVER_OK bit,
+ * hypervisor starts configuring all the virtqueues in the device. When the
+ * vhost_user has received VHOST_USER_SET_VRING_ENABLE for all the virtqueues,
+ * then it invokes VDPA driver callback dev_conf. APIs qstart and qcreate would
+ * be invoked from dev_conf callback to create the virtqueues, For further
+ * details refer SF-122427.
+ */
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_virtio_qcreate(
+       __in            efx_nic_t *enp,
+       __deref_out     efx_virtio_vq_t **evvpp);
+
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_virtio_qstart(
+       __in            efx_virtio_vq_t *evvp,
+       __in            efx_virtio_vq_cfg_t *evvcp,
+       __in_opt        efx_virtio_vq_dyncfg_t *evvdp);
+
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_virtio_qstop(
+       __in            efx_virtio_vq_t *evvp,
+       __out_opt       efx_virtio_vq_dyncfg_t *evvdp);
+
+LIBEFX_API
+extern                 void
+efx_virtio_qdestroy(
+       __in            efx_virtio_vq_t *evvp);
+
+/*
+ * Get the offset in the BAR of the doorbells for a VI.
+ * net device : doorbell offset of RX & TX queues
+ * block device : request doorbell offset in the BAR.
+ * For further details refer section of 4 of SF-119689
+ */
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_virtio_get_doorbell_offset(
+       __in            efx_virtio_vq_t *evvp,
+       __out           uint32_t *offsetp);
+
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_virtio_get_features(
+       __in            efx_nic_t *enp,
+       __in            efx_virtio_device_type_t type,
+       __out           uint64_t *featuresp);
+
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_virtio_verify_features(
+       __in            efx_nic_t *enp,
+       __in            efx_virtio_device_type_t type,
+       __in            uint64_t features);
+
+#endif /* EFSYS_OPT_VIRTIO */
+
 #ifdef __cplusplus
 }
 #endif