X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcommon%2Fsfc_efx%2Fbase%2Fefx.h;h=8e13075b0716128ef0001b785a3b0f62d5533b2d;hb=3dee345ab31a8cc685c9fe5ba3f90aa322ee1d48;hp=40c5968ea90e5accd9134214bae10387ff34cc4d;hpb=b75eb50d0469d20ee4723bae5820f5223a769df7;p=dpdk.git diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 40c5968ea9..8e13075b07 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -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. */ @@ -1603,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) @@ -1645,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; @@ -3871,7 +3889,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; @@ -4050,6 +4068,9 @@ efx_mae_fini( 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; } efx_mae_limits_t; LIBEFX_API @@ -4060,6 +4081,7 @@ efx_mae_get_limits( 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; @@ -4080,8 +4102,474 @@ 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); + +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); + +/* 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); + +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