/* 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.
*/
__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(
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;
* 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
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
__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_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;
__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
__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 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(
* 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
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;
__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(
#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