X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcommon%2Fsfc_efx%2Fbase%2Fefx_impl.h;h=3d1a4fdcb91df8da2b62ab2e81c29b28bd9230b3;hb=891408c45a63a35835e50ba792118fdc0ff32ae4;hp=7d6a31d298274d5429de42d177a44477569b51a2;hpb=5e111ed87999b2df4084b4d9c95643c98df1ba48;p=dpdk.git diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h index 7d6a31d298..3d1a4fdcb9 100644 --- a/drivers/common/sfc_efx/base/efx_impl.h +++ b/drivers/common/sfc_efx/base/efx_impl.h @@ -10,6 +10,7 @@ #include "efx.h" #include "efx_regs.h" #include "efx_regs_ef10.h" +#include "efx_regs_ef100.h" #if EFSYS_OPT_MCDI #include "efx_mcdi.h" #endif /* EFSYS_OPT_MCDI */ @@ -36,9 +37,13 @@ #include "medford2_impl.h" #endif /* EFSYS_OPT_MEDFORD2 */ -#if EFX_OPTS_EF10() +#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() #include "ef10_impl.h" -#endif /* EFX_OPTS_EF10() */ +#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */ + +#if EFSYS_OPT_RIVERHEAD +#include "rhead_impl.h" +#endif /* EFSYS_OPT_RIVERHEAD */ #ifdef __cplusplus extern "C" { @@ -72,6 +77,7 @@ typedef enum efx_mac_type_e { EFX_MAC_HUNTINGTON, EFX_MAC_MEDFORD, EFX_MAC_MEDFORD2, + EFX_MAC_RIVERHEAD, EFX_MAC_NTYPES } efx_mac_type_t; @@ -84,6 +90,8 @@ typedef struct efx_ev_ops_s { void (*eevo_qdestroy)(efx_evq_t *); efx_rc_t (*eevo_qprime)(efx_evq_t *, unsigned int); void (*eevo_qpost)(efx_evq_t *, uint16_t); + void (*eevo_qpoll)(efx_evq_t *, unsigned int *, + const efx_ev_callbacks_t *, void *); efx_rc_t (*eevo_qmoderate)(efx_evq_t *, unsigned int); #if EFSYS_OPT_QSTATS void (*eevo_qstats_update)(efx_evq_t *, efsys_stat_t *); @@ -295,8 +303,8 @@ efx_filter_reconfigure( #if EFSYS_OPT_TUNNEL typedef struct efx_tunnel_ops_s { - boolean_t (*eto_udp_encap_supported)(efx_nic_t *); efx_rc_t (*eto_reconfigure)(efx_nic_t *); + void (*eto_fini)(efx_nic_t *); } efx_tunnel_ops_t; #endif /* EFSYS_OPT_TUNNEL */ @@ -458,9 +466,9 @@ typedef struct efx_filter_s { #if EFSYS_OPT_SIENA siena_filter_t *ef_siena_filter; #endif /* EFSYS_OPT_SIENA */ -#if EFX_OPTS_EF10() +#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() ef10_filter_table_t *ef_ef10_filter_table; -#endif /* EFX_OPTS_EF10() */ +#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */ } efx_filter_t; #if EFSYS_OPT_SIENA @@ -481,9 +489,25 @@ siena_filter_tbl_clear( #if EFSYS_OPT_TUNNEL +/* State of a UDP tunnel table entry */ +typedef enum efx_tunnel_udp_entry_state_e { + EFX_TUNNEL_UDP_ENTRY_ADDED, /* Tunnel addition is requested */ + EFX_TUNNEL_UDP_ENTRY_REMOVED, /* Tunnel removal is requested */ + EFX_TUNNEL_UDP_ENTRY_APPLIED, /* Tunnel is applied by HW */ +} efx_tunnel_udp_entry_state_t; + +#if EFSYS_OPT_RIVERHEAD +typedef uint32_t efx_vnic_encap_rule_handle_t; +#endif /* EFSYS_OPT_RIVERHEAD */ + typedef struct efx_tunnel_udp_entry_s { uint16_t etue_port; /* host/cpu-endian */ uint16_t etue_protocol; + boolean_t etue_busy; + efx_tunnel_udp_entry_state_t etue_state; +#if EFSYS_OPT_RIVERHEAD + efx_vnic_encap_rule_handle_t etue_handle; +#endif /* EFSYS_OPT_RIVERHEAD */ } efx_tunnel_udp_entry_t; typedef struct efx_tunnel_cfg_s { @@ -756,6 +780,30 @@ typedef struct efx_proxy_ops_s { #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */ +#if EFSYS_OPT_MAE + +typedef struct efx_mae_field_cap_s { + uint32_t emfc_support; + boolean_t emfc_mask_affects_class; + boolean_t emfc_match_affects_class; +} efx_mae_field_cap_t; + +typedef struct efx_mae_s { + uint32_t em_max_n_action_prios; + /* + * The number of MAE field IDs recognised by the FW implementation. + * Any field ID greater than or equal to this value is unsupported. + */ + uint32_t em_max_nfields; + /** Action rule match field capabilities. */ + efx_mae_field_cap_t *em_action_rule_field_caps; + size_t em_action_rule_field_caps_size; + uint32_t em_max_n_outer_prios; + uint32_t em_encap_types_supported; +} efx_mae_t; + +#endif /* EFSYS_OPT_MAE */ + #define EFX_DRV_VER_MAX 20 typedef struct efx_drv_cfg_s { @@ -832,12 +880,13 @@ struct efx_nic_s { #endif /* EFSYS_OPT_SIENA */ int enu_unused; } en_u; -#if EFX_OPTS_EF10() +#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() union en_arch { struct { int ena_vi_base; int ena_vi_count; int ena_vi_shift; + uint32_t ena_fcw_base; #if EFSYS_OPT_VPD caddr_t ena_svpd; size_t ena_svpd_length; @@ -853,7 +902,7 @@ struct efx_nic_s { size_t ena_wc_mem_map_size; } ef10; } en_arch; -#endif /* EFX_OPTS_EF10() */ +#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */ #if EFSYS_OPT_EVB const efx_evb_ops_t *en_eeop; struct efx_vswitch_s *en_vswitchp; @@ -861,6 +910,9 @@ struct efx_nic_s { #if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER const efx_proxy_ops_t *en_epop; #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */ +#if EFSYS_OPT_MAE + efx_mae_t *en_maep; +#endif /* EFSYS_OPT_MAE */ }; #define EFX_FAMILY_IS_EF10(_enp) \ @@ -868,12 +920,20 @@ struct efx_nic_s { (_enp)->en_family == EFX_FAMILY_MEDFORD || \ (_enp)->en_family == EFX_FAMILY_HUNTINGTON) +#define EFX_FAMILY_IS_EF100(_enp) \ + ((_enp)->en_family == EFX_FAMILY_RIVERHEAD) + #define EFX_NIC_MAGIC 0x02121996 typedef boolean_t (*efx_ev_handler_t)(efx_evq_t *, efx_qword_t *, const efx_ev_callbacks_t *, void *); +#if EFSYS_OPT_EV_EXTENDED_WIDTH +typedef boolean_t (*efx_ev_ew_handler_t)(efx_evq_t *, efx_xword_t *, + const efx_ev_callbacks_t *, void *); +#endif /* EFSYS_OPT_EV_EXTENDED_WIDTH */ + typedef struct efx_evq_rxq_state_s { unsigned int eers_rx_read_ptr; unsigned int eers_rx_mask; @@ -906,6 +966,11 @@ struct efx_evq_s { efx_ev_handler_t ee_mcdi; #endif /* EFSYS_OPT_MCDI */ +#if EFSYS_OPT_DESC_PROXY + efx_ev_ew_handler_t ee_ew_txq_desc; + efx_ev_ew_handler_t ee_ew_virtq_desc; +#endif /* EFSYS_OPT_DESC_PROXY */ + efx_evq_rxq_state_t ee_rxq_state[EFX_EV_RX_NLABELS]; }; @@ -933,6 +998,7 @@ struct efx_rxq_s { size_t er_buf_size; efsys_mem_t *er_esmp; efx_evq_rxq_state_t *er_ev_qstate; + efx_rx_prefix_layout_t er_prefix_layout; }; #define EFX_RXQ_MAGIC 0x15022005 @@ -1002,6 +1068,10 @@ struct efx_txq_s { rev = 'F'; \ break; \ \ + case EFX_FAMILY_RIVERHEAD: \ + rev = 'G'; \ + break; \ + \ default: \ rev = '?'; \ break; \ @@ -1098,6 +1168,9 @@ struct efx_txq_s { * Code used on EF10 *must* use EFX_BAR_VI_*() macros for per-VI registers, * to ensure the correct runtime VI window size is used on Medford2. * + * Code used on EF100 *must* use EFX_BAR_FCW_* macros for function control + * window registers, to ensure the correct starting offset is used. + * * Siena-only code may continue using EFX_BAR_TBL_*() macros for VI registers. */ @@ -1202,6 +1275,41 @@ struct efx_txq_s { _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) +/* + * Accessors for memory BAR function control window registers. + * + * The function control window is located at an offset which can be + * non-zero in case of Riverhead. + */ + +#if EFSYS_OPT_RIVERHEAD + +#define EFX_BAR_FCW_READD(_enp, _reg, _edp) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_BAR_READD((_enp)->en_esbp, _reg ## _OFST + \ + (_enp)->en_arch.ef10.ena_fcw_base, \ + (_edp), B_FALSE); \ + EFSYS_PROBE3(efx_bar_fcw_readd, const char *, #_reg, \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_edp)->ed_u32[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_FCW_WRITED(_enp, _reg, _edp) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_PROBE3(efx_bar_fcw_writed, const char *, #_reg, \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_edp)->ed_u32[0]); \ + EFSYS_BAR_WRITED((_enp)->en_esbp, _reg ## _OFST + \ + (_enp)->en_arch.ef10.ena_fcw_base, \ + (_edp), B_FALSE); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#endif /* EFSYS_OPT_RIVERHEAD */ + /* * Accessors for memory BAR per-VI registers. * @@ -1277,15 +1385,16 @@ struct efx_txq_s { _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) -#define EFX_DMA_SYNC_QUEUE_FOR_DEVICE(_esmp, _entries, _wptr, _owptr) \ +#define EFX_DMA_SYNC_QUEUE_FOR_DEVICE(_esmp, _entries, _desc_size, \ + _wptr, _owptr) \ do { \ unsigned int _new = (_wptr); \ unsigned int _old = (_owptr); \ \ if ((_new) >= (_old)) \ EFSYS_DMA_SYNC_FOR_DEVICE((_esmp), \ - (_old) * sizeof (efx_desc_t), \ - ((_new) - (_old)) * sizeof (efx_desc_t)); \ + (_old) * (_desc_size), \ + ((_new) - (_old)) * (_desc_size)); \ else \ /* \ * It is cheaper to sync entire map than sync \ @@ -1294,7 +1403,7 @@ struct efx_txq_s { */ \ EFSYS_DMA_SYNC_FOR_DEVICE((_esmp), \ 0, \ - (_entries) * sizeof (efx_desc_t)); \ + (_entries) * (_desc_size)); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) @@ -1393,6 +1502,74 @@ efx_mcdi_get_workarounds( __out_opt uint32_t *implementedp, __out_opt uint32_t *enabledp); +#if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() + +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_mcdi_init_evq( + __in efx_nic_t *enp, + __in unsigned int instance, + __in efsys_mem_t *esmp, + __in size_t nevs, + __in uint32_t irq, + __in uint32_t us, + __in uint32_t flags, + __in boolean_t low_latency); + +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_mcdi_fini_evq( + __in efx_nic_t *enp, + __in uint32_t instance); + +typedef struct efx_mcdi_init_rxq_params_s { + boolean_t disable_scatter; + boolean_t want_inner_classes; + uint32_t buf_size; + uint32_t ps_buf_size; + uint32_t es_bufs_per_desc; + uint32_t es_max_dma_len; + uint32_t es_buf_stride; + uint32_t hol_block_timeout; + uint32_t prefix_id; +} efx_mcdi_init_rxq_params_t; + +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_mcdi_init_rxq( + __in efx_nic_t *enp, + __in uint32_t ndescs, + __in efx_evq_t *eep, + __in uint32_t label, + __in uint32_t instance, + __in efsys_mem_t *esmp, + __in const efx_mcdi_init_rxq_params_t *params); + +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_mcdi_fini_rxq( + __in efx_nic_t *enp, + __in uint32_t instance); + +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_mcdi_init_txq( + __in efx_nic_t *enp, + __in uint32_t ndescs, + __in uint32_t target_evq, + __in uint32_t label, + __in uint32_t instance, + __in uint16_t flags, + __in efsys_mem_t *esmp); + +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_mcdi_fini_txq( + __in efx_nic_t *enp, + __in uint32_t instance); + +#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */ + #endif /* EFSYS_OPT_MCDI */ #if EFSYS_OPT_MAC_STATS @@ -1434,6 +1611,141 @@ efx_mcdi_mac_stats( #endif /* EFSYS_OPT_MAC_STATS */ +#if EFSYS_OPT_PCI + +/* + * Find the next extended capability in a PCI device's config space + * with specified capability id. + * Passing 0 offset makes the function search from the start. + * If search succeeds, found capability is in modified offset. + * + * Returns ENOENT if a capability is not found. + */ +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_pci_config_find_next_ext_cap( + __in efsys_pci_config_t *espcp, + __in const efx_pci_ops_t *epop, + __in uint16_t cap_id, + __inout size_t *offsetp); + +/* + * Get the next extended capability in a PCI device's config space. + * Passing 0 offset makes the function get the first capability. + * If search succeeds, the capability is in modified offset. + * + * Returns ENOENT if there is no next capability. + */ +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_pci_config_next_ext_cap( + __in efsys_pci_config_t *espcp, + __in const efx_pci_ops_t *epop, + __inout size_t *offsetp); + +/* + * Find the next Xilinx capabilities table location by searching + * PCI extended capabilities. + * + * Returns ENOENT if a table location is not found. + */ +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_pci_find_next_xilinx_cap_table( + __in efsys_pci_config_t *espcp, + __in const efx_pci_ops_t *epop, + __inout size_t *pci_cap_offsetp, + __out unsigned int *xilinx_tbl_barp, + __out efsys_dma_addr_t *xilinx_tbl_offsetp); + +/* + * Read a Xilinx extended PCI capability that gives the location + * of a Xilinx capabilities table. + * + * Returns ENOENT if the extended PCI capability does not contain + * Xilinx capabilities table locator. + */ +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_pci_read_ext_cap_xilinx_table( + __in efsys_pci_config_t *espcp, + __in const efx_pci_ops_t *epop, + __in size_t cap_offset, + __out unsigned int *barp, + __out efsys_dma_addr_t *offsetp); + +/* + * Find a capability with specified format_id in a Xilinx capabilities table. + * Searching is started from provided offset, taking skip_first into account. + * If search succeeds, found capability is in modified offset. + * + * Returns ENOENT if an entry with specified format id is not found. + */ +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_pci_xilinx_cap_tbl_find( + __in efsys_bar_t *esbp, + __in uint32_t format_id, + __in boolean_t skip_first, + __inout efsys_dma_addr_t *entry_offsetp); + +#endif /* EFSYS_OPT_PCI */ + +#if EFSYS_OPT_MAE + +struct efx_mae_match_spec_s { + efx_mae_rule_type_t emms_type; + uint32_t emms_prio; + union emms_mask_value_pairs { + uint8_t action[MAE_FIELD_MASK_VALUE_PAIRS_LEN]; + } emms_mask_value_pairs; +}; + +typedef enum efx_mae_action_e { + /* These actions are strictly ordered. */ + EFX_MAE_ACTION_VLAN_POP, + EFX_MAE_ACTION_VLAN_PUSH, + + /* + * These actions are not strictly ordered and can + * be passed by a client in any order (before DELIVER). + * However, these enumerants must be kept compactly + * in the end of the enumeration (before DELIVER). + */ + EFX_MAE_ACTION_FLAG, + EFX_MAE_ACTION_MARK, + + /* DELIVER is always the last action. */ + EFX_MAE_ACTION_DELIVER, + + EFX_MAE_NACTIONS +} efx_mae_action_t; + +/* MAE VLAN_POP action can handle 1 or 2 tags. */ +#define EFX_MAE_VLAN_POP_MAX_NTAGS (2) + +/* MAE VLAN_PUSH action can handle 1 or 2 tags. */ +#define EFX_MAE_VLAN_PUSH_MAX_NTAGS (2) + +typedef struct efx_mae_action_vlan_push_s { + uint16_t emavp_tpid_be; + uint16_t emavp_tci_be; +} efx_mae_action_vlan_push_t; + +struct efx_mae_actions_s { + /* Bitmap of actions in spec, indexed by action type */ + uint32_t ema_actions; + + unsigned int ema_n_vlan_tags_to_pop; + unsigned int ema_n_vlan_tags_to_push; + efx_mae_action_vlan_push_t ema_vlan_push_descs[ + EFX_MAE_VLAN_PUSH_MAX_NTAGS]; + uint32_t ema_mark_value; + efx_mport_sel_t ema_deliver_mport; +}; + +#endif /* EFSYS_OPT_MAE */ + #ifdef __cplusplus } #endif