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