Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * 3 : : * Copyright(c) 2019-2021 Xilinx, Inc. 4 : : * Copyright(c) 2016-2019 Solarflare Communications Inc. 5 : : * 6 : : * This software was jointly developed between OKTET Labs (under contract 7 : : * for Solarflare) and Solarflare Communications, Inc. 8 : : */ 9 : : 10 : : #ifndef _SFC_H 11 : : #define _SFC_H 12 : : 13 : : #include <stdbool.h> 14 : : 15 : : #include <rte_pci.h> 16 : : #include <bus_pci_driver.h> 17 : : #include <ethdev_driver.h> 18 : : #include <rte_kvargs.h> 19 : : #include <rte_spinlock.h> 20 : : #include <rte_atomic.h> 21 : : 22 : : #include "efx.h" 23 : : 24 : : #include "sfc_efx_mcdi.h" 25 : : #include "sfc_efx.h" 26 : : 27 : : #include "sfc_debug.h" 28 : : #include "sfc_log.h" 29 : : #include "sfc_filter.h" 30 : : #include "sfc_flow_rss.h" 31 : : #include "sfc_flow_tunnel.h" 32 : : #include "sfc_sriov.h" 33 : : #include "sfc_mae.h" 34 : : #include "sfc_tbls.h" 35 : : #include "sfc_dp.h" 36 : : #include "sfc_sw_stats.h" 37 : : #include "sfc_repr_proxy.h" 38 : : #include "sfc_service.h" 39 : : #include "sfc_ethdev_state.h" 40 : : #include "sfc_nic_dma_dp.h" 41 : : 42 : : #ifdef __cplusplus 43 : : extern "C" { 44 : : #endif 45 : : 46 : : enum sfc_dev_filter_mode { 47 : : SFC_DEV_FILTER_MODE_PROMISC = 0, 48 : : SFC_DEV_FILTER_MODE_ALLMULTI, 49 : : 50 : : SFC_DEV_FILTER_NMODES 51 : : }; 52 : : 53 : : struct sfc_intr { 54 : : efx_intr_type_t type; 55 : : rte_intr_callback_fn handler; 56 : : boolean_t lsc_intr; 57 : : boolean_t rxq_intr; 58 : : }; 59 : : 60 : : struct sfc_rxq; 61 : : struct sfc_txq; 62 : : 63 : : struct sfc_rxq_info; 64 : : struct sfc_txq_info; 65 : : struct sfc_dp_rx; 66 : : 67 : : struct sfc_port { 68 : : unsigned int lsc_seq; 69 : : 70 : : efx_phy_lane_count_t phy_lane_count_active; 71 : : efx_phy_lane_count_t phy_lane_count_req; 72 : : uint32_t phy_adv_cap_mask; 73 : : uint32_t phy_adv_cap; 74 : : uint32_t fec_cfg; 75 : : bool fec_auto; 76 : : 77 : : unsigned int flow_ctrl; 78 : : boolean_t flow_ctrl_autoneg; 79 : : boolean_t include_fcs; 80 : : boolean_t vlan_strip; 81 : : size_t pdu; 82 : : 83 : : /* 84 : : * Flow API isolated mode overrides promisc and allmulti settings; 85 : : * they won't be applied if isolated mode is active 86 : : */ 87 : : boolean_t promisc; 88 : : boolean_t allmulti; 89 : : 90 : : struct rte_ether_addr default_mac_addr; 91 : : 92 : : unsigned int max_mcast_addrs; 93 : : unsigned int nb_mcast_addrs; 94 : : uint8_t *mcast_addrs; 95 : : 96 : : uint64_t *mac_stats_buf; 97 : : unsigned int mac_stats_nb_supported; 98 : : efsys_mem_t mac_stats_dma_mem; 99 : : boolean_t mac_stats_reset_pending; 100 : : uint16_t mac_stats_update_period_ms; 101 : : uint32_t mac_stats_update_generation; 102 : : boolean_t mac_stats_periodic_dma_supported; 103 : : uint64_t mac_stats_last_request_timestamp; 104 : : 105 : : uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES]; 106 : : 107 : : unsigned int mac_stats_by_id[EFX_MAC_NSTATS]; 108 : : 109 : : uint64_t ipackets; 110 : : }; 111 : : 112 : : struct sfc_rss_hf_rte_to_efx { 113 : : uint64_t rte; 114 : : efx_rx_hash_type_t efx; 115 : : }; 116 : : 117 : : struct sfc_rss { 118 : : unsigned int channels; 119 : : efx_rx_scale_context_type_t context_type; 120 : : efx_rx_hash_support_t hash_support; 121 : : efx_rx_hash_alg_t hash_alg; 122 : : unsigned int hf_map_nb_entries; 123 : : struct sfc_rss_hf_rte_to_efx *hf_map; 124 : : 125 : : efx_rx_hash_type_t hash_types; 126 : : unsigned int tbl[EFX_RSS_TBL_SIZE]; 127 : : uint8_t key[EFX_RSS_KEY_SIZE]; 128 : : 129 : : struct sfc_flow_rss_ctx dummy_ctx; 130 : : }; 131 : : 132 : : /* Adapter private data shared by primary and secondary processes */ 133 : : struct sfc_adapter_shared { 134 : : unsigned int rxq_count; 135 : : struct sfc_rxq_info *rxq_info; 136 : : unsigned int ethdev_rxq_count; 137 : : 138 : : unsigned int txq_count; 139 : : struct sfc_txq_info *txq_info; 140 : : unsigned int ethdev_txq_count; 141 : : 142 : : struct sfc_rss rss; 143 : : 144 : : boolean_t isolated; 145 : : uint32_t tunnel_encaps; 146 : : 147 : : char log_prefix[SFC_LOG_PREFIX_MAX]; 148 : : struct rte_pci_addr pci_addr; 149 : : uint16_t port_id; 150 : : 151 : : char *dp_rx_name; 152 : : char *dp_tx_name; 153 : : 154 : : bool counters_rxq_allocated; 155 : : unsigned int nb_repr_rxq; 156 : : unsigned int nb_repr_txq; 157 : : 158 : : struct sfc_nic_dma_info nic_dma_info; 159 : : 160 : : /* 161 : : * Snapshot of the 'rte_eth_dev_info_get' output created by the primary 162 : : * process attach path for the secondary process to use in its own 163 : : * implementation of the 'dev_infos_get' method. 164 : : * 165 : : * Some driver-computed fields derived from mutable post-attach state 166 : : * are knowingly stale, which is acceptable for the secondary process. 167 : : * 168 : : * This also contains a handful of stale fields which are normally 169 : : * set by the ethdev layer upon invocation of the 'dev_infos_get', 170 : : * so they will be overridden anyway in the secondary process. 171 : : */ 172 : : struct rte_eth_dev_info dev_info_cache; 173 : : /* 174 : : * Set to 'true' by the probe function from the primary process. The 175 : : * secondary 'dev_infos_get' returns '-EAGAIN' when this is 'false'. 176 : : */ 177 : : RTE_ATOMIC(bool) dev_info_cache_is_valid; 178 : : }; 179 : : 180 : : /* Adapter process private data */ 181 : : struct sfc_adapter_priv { 182 : : struct sfc_adapter_shared *shared; 183 : : const struct sfc_dp_rx *dp_rx; 184 : : const struct sfc_dp_tx *dp_tx; 185 : : uint32_t logtype_main; 186 : : }; 187 : : 188 : : static inline struct sfc_adapter_priv * 189 : : sfc_adapter_priv_by_eth_dev(struct rte_eth_dev *eth_dev) 190 : : { 191 [ # # # # : 0 : struct sfc_adapter_priv *sap = eth_dev->process_private; # # # # # # # # # # # # # # # # # # # # # # # # ] 192 : : 193 : : SFC_ASSERT(sap != NULL); 194 : : return sap; 195 : : } 196 : : 197 : : /* RxQ dedicated for counters (counter only RxQ) data */ 198 : : struct sfc_counter_rxq { 199 : : unsigned int state; 200 : : #define SFC_COUNTER_RXQ_ATTACHED 0x1 201 : : #define SFC_COUNTER_RXQ_INITIALIZED 0x2 202 : : sfc_sw_index_t sw_index; 203 : : struct rte_mempool *mp; 204 : : }; 205 : : 206 : : struct sfc_sw_stat_data { 207 : : const struct sfc_sw_stat_descr *descr; 208 : : /* Cache fragment */ 209 : : uint64_t *cache; 210 : : }; 211 : : 212 : : struct sfc_sw_stats { 213 : : /* Number extended statistics provided by SW stats */ 214 : : unsigned int xstats_count; 215 : : /* Supported SW statistics */ 216 : : struct sfc_sw_stat_data *supp; 217 : : unsigned int supp_count; 218 : : 219 : : /* Cache for all supported SW statistics */ 220 : : uint64_t *cache; 221 : : unsigned int cache_count; 222 : : 223 : : uint64_t *reset_vals; 224 : : /* Location of per-queue reset values for packets/bytes in reset_vals */ 225 : : uint64_t *reset_rx_pkts; 226 : : uint64_t *reset_rx_bytes; 227 : : uint64_t *reset_tx_pkts; 228 : : uint64_t *reset_tx_bytes; 229 : : 230 : : rte_spinlock_t queues_bitmap_lock; 231 : : void *queues_bitmap_mem; 232 : : struct rte_bitmap *queues_bitmap; 233 : : }; 234 : : 235 : : /* Adapter private data */ 236 : : struct sfc_adapter { 237 : : /* 238 : : * It must be the first field of the sfc_adapter structure since 239 : : * sfc_adapter is the primary process private data (i.e. process 240 : : * private data plus additional primary process specific data). 241 : : */ 242 : : struct sfc_adapter_priv priv; 243 : : 244 : : /* 245 : : * PMD setup and configuration is not thread safe. Since it is not 246 : : * performance sensitive, it is better to guarantee thread-safety 247 : : * and add device level lock. Adapter control operations which 248 : : * change its state should acquire the lock. 249 : : */ 250 : : rte_spinlock_t lock; 251 : : enum sfc_ethdev_state state; 252 : : struct rte_eth_dev *eth_dev; 253 : : struct rte_kvargs *kvargs; 254 : : int socket_id; 255 : : efsys_bar_t mem_bar; 256 : : /* Function control window offset */ 257 : : efsys_dma_addr_t fcw_offset; 258 : : efx_family_t family; 259 : : efx_nic_t *nic; 260 : : rte_spinlock_t nic_lock; 261 : : rte_atomic32_t restart_required; 262 : : 263 : : struct sfc_efx_mcdi mcdi; 264 : : struct sfc_sriov sriov; 265 : : struct sfc_intr intr; 266 : : struct sfc_port port; 267 : : struct sfc_sw_stats sw_stats; 268 : : struct sfc_flow_rss flow_rss; 269 : : /* Registry of contexts used in Flow Tunnel (FT) offload */ 270 : : struct sfc_ft_ctx ft_ctx_pool[SFC_FT_MAX_NTUNNELS]; 271 : : struct sfc_filter filter; 272 : : struct sfc_mae mae; 273 : : struct sfc_tbls hw_tables; 274 : : struct sfc_repr_proxy repr_proxy; 275 : : 276 : : struct sfc_flow_indir_actions flow_indir_actions; 277 : : struct sfc_flow_list flow_list; 278 : : 279 : : unsigned int rxq_max; 280 : : unsigned int txq_max; 281 : : 282 : : unsigned int rxq_max_entries; 283 : : unsigned int rxq_min_entries; 284 : : 285 : : unsigned int txq_max_entries; 286 : : unsigned int txq_min_entries; 287 : : 288 : : unsigned int evq_max_entries; 289 : : unsigned int evq_min_entries; 290 : : 291 : : uint32_t evq_flags; 292 : : unsigned int evq_count; 293 : : 294 : : unsigned int mgmt_evq_index; 295 : : /* 296 : : * The lock is used to serialise management event queue polling 297 : : * which can be done from different context. Also the lock 298 : : * guarantees that mgmt_evq_running is preserved while the lock 299 : : * is held. It is used to serialise polling and start/stop 300 : : * operations. 301 : : * 302 : : * Locks which may be held when the lock is acquired: 303 : : * - adapter lock, when: 304 : : * - device start/stop to change mgmt_evq_running 305 : : * - any control operations in client side MCDI proxy handling to 306 : : * poll management event queue waiting for proxy response 307 : : * - MCDI lock, when: 308 : : * - any control operations in client side MCDI proxy handling to 309 : : * poll management event queue waiting for proxy response 310 : : * 311 : : * Locks which are acquired with the lock held: 312 : : * - nic_lock, when: 313 : : * - MC event processing on management event queue polling 314 : : * (e.g. MC REBOOT or BADASSERT events) 315 : : */ 316 : : rte_spinlock_t mgmt_evq_lock; 317 : : bool mgmt_evq_running; 318 : : struct sfc_evq *mgmt_evq; 319 : : 320 : : struct sfc_counter_rxq counter_rxq; 321 : : 322 : : struct sfc_rxq *rxq_ctrl; 323 : : struct sfc_txq *txq_ctrl; 324 : : 325 : : boolean_t tso; 326 : : boolean_t tso_encap; 327 : : 328 : : uint64_t negotiated_rx_metadata; 329 : : 330 : : uint32_t rxd_wait_timeout_ns; 331 : : 332 : : bool switchdev; 333 : : 334 : : bool link_ev_need_poll; 335 : : }; 336 : : 337 : : static inline struct sfc_adapter_shared * 338 : : sfc_adapter_shared_by_eth_dev(struct rte_eth_dev *eth_dev) 339 : : { 340 [ # # # # : 0 : struct sfc_adapter_shared *sas = eth_dev->data->dev_private; # # # # # # # ] 341 : : 342 : : return sas; 343 : : } 344 : : 345 : : static inline struct sfc_adapter * 346 : : sfc_adapter_by_eth_dev(struct rte_eth_dev *eth_dev) 347 : : { 348 : : struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(eth_dev); 349 : : 350 : : SFC_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); 351 : : 352 : : return container_of(sap, struct sfc_adapter, priv); 353 : : } 354 : : 355 : : static inline struct sfc_adapter_shared * 356 : : sfc_sa2shared(struct sfc_adapter *sa) 357 : : { 358 [ # # # # : 0 : return sa->priv.shared; # # # # # # ] 359 : : } 360 : : 361 : : /* 362 : : * Add wrapper functions to acquire/release lock to be able to remove or 363 : : * change the lock in one place. 364 : : */ 365 : : 366 : : #define sfc_adapter_lock_init(sa) rte_spinlock_init(&(sa)->lock) 367 : : #define sfc_adapter_is_locked(sa) rte_spinlock_is_locked(&(sa)->lock) 368 : : #define sfc_adapter_lock(sa) rte_spinlock_lock(&(sa)->lock) 369 : : #define sfc_adapter_trylock(sa) rte_spinlock_trylock(&(sa)->lock) 370 : : #define sfc_adapter_unlock(sa) rte_spinlock_unlock(&(sa)->lock) 371 : : #define sfc_adapter_lock_fini(sa) RTE_SET_USED(sa) 372 : : 373 : : static inline unsigned int 374 : : sfc_nb_counter_rxq(const struct sfc_adapter_shared *sas) 375 : : { 376 : 0 : return sas->counters_rxq_allocated ? 1 : 0; 377 : : } 378 : : 379 : : bool sfc_repr_supported(const struct sfc_adapter *sa); 380 : : bool sfc_repr_available(const struct sfc_adapter_shared *sas); 381 : : 382 : : static inline unsigned int 383 : : sfc_repr_nb_rxq(const struct sfc_adapter_shared *sas) 384 : : { 385 [ # # # # : 0 : return sas->nb_repr_rxq; # # # # # # # # # # ] 386 : : } 387 : : 388 : : static inline unsigned int 389 : : sfc_repr_nb_txq(const struct sfc_adapter_shared *sas) 390 : : { 391 [ # # # # : 0 : return sas->nb_repr_txq; # # # # # # # # ] 392 : : } 393 : : 394 : : /** Get the number of milliseconds since boot from the default timer */ 395 : : static inline uint64_t 396 : : sfc_get_system_msecs(void) 397 : : { 398 [ # # ]: 0 : return rte_get_timer_cycles() * MS_PER_S / rte_get_timer_hz(); 399 : : } 400 : : 401 : : int sfc_dma_alloc(struct sfc_adapter *sa, const char *name, uint16_t id, 402 : : efx_nic_dma_addr_type_t addr_type, size_t len, int socket_id, 403 : : efsys_mem_t *esmp); 404 : : void sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp); 405 : : 406 : : uint32_t sfc_register_logtype(const struct rte_pci_addr *pci_addr, 407 : : const char *lt_prefix_str, 408 : : uint32_t ll_default); 409 : : 410 : : int sfc_probe(struct sfc_adapter *sa); 411 : : void sfc_unprobe(struct sfc_adapter *sa); 412 : : int sfc_attach(struct sfc_adapter *sa); 413 : : void sfc_pre_detach(struct sfc_adapter *sa); 414 : : void sfc_detach(struct sfc_adapter *sa); 415 : : int sfc_start(struct sfc_adapter *sa); 416 : : void sfc_stop(struct sfc_adapter *sa); 417 : : 418 : : void sfc_schedule_restart(struct sfc_adapter *sa); 419 : : 420 : : int sfc_mcdi_init(struct sfc_adapter *sa); 421 : : void sfc_mcdi_fini(struct sfc_adapter *sa); 422 : : 423 : : int sfc_configure(struct sfc_adapter *sa); 424 : : void sfc_close(struct sfc_adapter *sa); 425 : : 426 : : int sfc_intr_attach(struct sfc_adapter *sa); 427 : : void sfc_intr_detach(struct sfc_adapter *sa); 428 : : int sfc_intr_configure(struct sfc_adapter *sa); 429 : : void sfc_intr_close(struct sfc_adapter *sa); 430 : : int sfc_intr_start(struct sfc_adapter *sa); 431 : : void sfc_intr_stop(struct sfc_adapter *sa); 432 : : 433 : : int sfc_port_attach(struct sfc_adapter *sa); 434 : : void sfc_port_detach(struct sfc_adapter *sa); 435 : : int sfc_port_configure(struct sfc_adapter *sa); 436 : : void sfc_port_close(struct sfc_adapter *sa); 437 : : int sfc_port_start(struct sfc_adapter *sa); 438 : : void sfc_port_stop(struct sfc_adapter *sa); 439 : : void sfc_port_link_mode_to_info(efx_link_mode_t link_mode, uint32_t phy_cap_req, 440 : : struct rte_eth_link *link_info); 441 : : int sfc_port_update_mac_stats(struct sfc_adapter *sa, boolean_t manual_update); 442 : : int sfc_port_get_mac_stats(struct sfc_adapter *sa, struct rte_eth_xstat *xstats, 443 : : unsigned int xstats_count, unsigned int *nb_written); 444 : : int sfc_port_get_mac_stats_by_id(struct sfc_adapter *sa, const uint64_t *ids, 445 : : uint64_t *values, unsigned int n); 446 : : int sfc_port_reset_mac_stats(struct sfc_adapter *sa); 447 : : int sfc_set_rx_mode(struct sfc_adapter *sa); 448 : : int sfc_set_rx_mode_unchecked(struct sfc_adapter *sa); 449 : : 450 : : struct sfc_hw_switch_id; 451 : : 452 : : int sfc_hw_switch_id_init(struct sfc_adapter *sa, 453 : : struct sfc_hw_switch_id **idp); 454 : : void sfc_hw_switch_id_fini(struct sfc_adapter *sa, 455 : : struct sfc_hw_switch_id *idp); 456 : : bool sfc_hw_switch_ids_equal(const struct sfc_hw_switch_id *left, 457 : : const struct sfc_hw_switch_id *right); 458 : : 459 : : #ifdef __cplusplus 460 : : } 461 : : #endif 462 : : 463 : : #endif /* _SFC_H */