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 26 #include "sfc_debug.h" 27 #include "sfc_log.h" 28 #include "sfc_filter.h" 29 #include "sfc_sriov.h" 30 #include "sfc_mae.h" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* 37 * +---------------+ 38 * | UNINITIALIZED |<-----------+ 39 * +---------------+ | 40 * |.eth_dev_init |.eth_dev_uninit 41 * V | 42 * +---------------+------------+ 43 * | INITIALIZED | 44 * +---------------+<-----------<---------------+ 45 * |.dev_configure | | 46 * V |failed | 47 * +---------------+------------+ | 48 * | CONFIGURING | | 49 * +---------------+----+ | 50 * |success | | 51 * | | +---------------+ 52 * | | | CLOSING | 53 * | | +---------------+ 54 * | | ^ 55 * V |.dev_configure | 56 * +---------------+----+ |.dev_close 57 * | CONFIGURED |----------------------------+ 58 * +---------------+<-----------+ 59 * |.dev_start | 60 * V | 61 * +---------------+ | 62 * | STARTING |------------^ 63 * +---------------+ failed | 64 * |success | 65 * | +---------------+ 66 * | | STOPPING | 67 * | +---------------+ 68 * | ^ 69 * V |.dev_stop 70 * +---------------+------------+ 71 * | STARTED | 72 * +---------------+ 73 */ 74 enum sfc_adapter_state { 75 SFC_ADAPTER_UNINITIALIZED = 0, 76 SFC_ADAPTER_INITIALIZED, 77 SFC_ADAPTER_CONFIGURING, 78 SFC_ADAPTER_CONFIGURED, 79 SFC_ADAPTER_CLOSING, 80 SFC_ADAPTER_STARTING, 81 SFC_ADAPTER_STARTED, 82 SFC_ADAPTER_STOPPING, 83 84 SFC_ADAPTER_NSTATES 85 }; 86 87 enum sfc_dev_filter_mode { 88 SFC_DEV_FILTER_MODE_PROMISC = 0, 89 SFC_DEV_FILTER_MODE_ALLMULTI, 90 91 SFC_DEV_FILTER_NMODES 92 }; 93 94 struct sfc_intr { 95 efx_intr_type_t type; 96 rte_intr_callback_fn handler; 97 boolean_t lsc_intr; 98 boolean_t rxq_intr; 99 }; 100 101 struct sfc_rxq; 102 struct sfc_txq; 103 104 struct sfc_rxq_info; 105 struct sfc_txq_info; 106 struct sfc_dp_rx; 107 108 struct sfc_port { 109 unsigned int lsc_seq; 110 111 uint32_t phy_adv_cap_mask; 112 uint32_t phy_adv_cap; 113 114 unsigned int flow_ctrl; 115 boolean_t flow_ctrl_autoneg; 116 size_t pdu; 117 118 /* 119 * Flow API isolated mode overrides promisc and allmulti settings; 120 * they won't be applied if isolated mode is active 121 */ 122 boolean_t promisc; 123 boolean_t allmulti; 124 125 struct rte_ether_addr default_mac_addr; 126 127 unsigned int max_mcast_addrs; 128 unsigned int nb_mcast_addrs; 129 uint8_t *mcast_addrs; 130 131 rte_spinlock_t mac_stats_lock; 132 uint64_t *mac_stats_buf; 133 unsigned int mac_stats_nb_supported; 134 efsys_mem_t mac_stats_dma_mem; 135 boolean_t mac_stats_reset_pending; 136 uint16_t mac_stats_update_period_ms; 137 uint32_t mac_stats_update_generation; 138 boolean_t mac_stats_periodic_dma_supported; 139 uint64_t mac_stats_last_request_timestamp; 140 141 uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES]; 142 143 uint64_t ipackets; 144 }; 145 146 struct sfc_rss_hf_rte_to_efx { 147 uint64_t rte; 148 efx_rx_hash_type_t efx; 149 }; 150 151 struct sfc_rss { 152 unsigned int channels; 153 efx_rx_scale_context_type_t context_type; 154 efx_rx_hash_support_t hash_support; 155 efx_rx_hash_alg_t hash_alg; 156 unsigned int hf_map_nb_entries; 157 struct sfc_rss_hf_rte_to_efx *hf_map; 158 159 efx_rx_hash_type_t hash_types; 160 unsigned int tbl[EFX_RSS_TBL_SIZE]; 161 uint8_t key[EFX_RSS_KEY_SIZE]; 162 163 uint32_t dummy_rss_context; 164 }; 165 166 /* Adapter private data shared by primary and secondary processes */ 167 struct sfc_adapter_shared { 168 unsigned int rxq_count; 169 struct sfc_rxq_info *rxq_info; 170 171 unsigned int txq_count; 172 struct sfc_txq_info *txq_info; 173 174 struct sfc_rss rss; 175 176 boolean_t isolated; 177 uint32_t tunnel_encaps; 178 179 char log_prefix[SFC_LOG_PREFIX_MAX]; 180 struct rte_pci_addr pci_addr; 181 uint16_t port_id; 182 183 char *dp_rx_name; 184 char *dp_tx_name; 185 }; 186 187 /* Adapter process private data */ 188 struct sfc_adapter_priv { 189 struct sfc_adapter_shared *shared; 190 const struct sfc_dp_rx *dp_rx; 191 const struct sfc_dp_tx *dp_tx; 192 uint32_t logtype_main; 193 }; 194 195 static inline struct sfc_adapter_priv * 196 sfc_adapter_priv_by_eth_dev(struct rte_eth_dev *eth_dev) 197 { 198 struct sfc_adapter_priv *sap = eth_dev->process_private; 199 200 SFC_ASSERT(sap != NULL); 201 return sap; 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_adapter_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_filter filter; 237 struct sfc_mae mae; 238 239 struct sfc_flow_list flow_list; 240 241 unsigned int rxq_max; 242 unsigned int txq_max; 243 244 unsigned int rxq_max_entries; 245 unsigned int rxq_min_entries; 246 247 unsigned int txq_max_entries; 248 unsigned int txq_min_entries; 249 250 unsigned int evq_max_entries; 251 unsigned int evq_min_entries; 252 253 uint32_t evq_flags; 254 unsigned int evq_count; 255 256 unsigned int mgmt_evq_index; 257 /* 258 * The lock is used to serialise management event queue polling 259 * which can be done from different context. Also the lock 260 * guarantees that mgmt_evq_running is preserved while the lock 261 * is held. It is used to serialise polling and start/stop 262 * operations. 263 * 264 * Locks which may be held when the lock is acquired: 265 * - adapter lock, when: 266 * - device start/stop to change mgmt_evq_running 267 * - any control operations in client side MCDI proxy handling to 268 * poll management event queue waiting for proxy response 269 * - MCDI lock, when: 270 * - any control operations in client side MCDI proxy handling to 271 * poll management event queue waiting for proxy response 272 * 273 * Locks which are acquired with the lock held: 274 * - nic_lock, when: 275 * - MC event processing on management event queue polling 276 * (e.g. MC REBOOT or BADASSERT events) 277 */ 278 rte_spinlock_t mgmt_evq_lock; 279 bool mgmt_evq_running; 280 struct sfc_evq *mgmt_evq; 281 282 struct sfc_rxq *rxq_ctrl; 283 struct sfc_txq *txq_ctrl; 284 285 boolean_t tso; 286 boolean_t tso_encap; 287 288 uint32_t rxd_wait_timeout_ns; 289 }; 290 291 static inline struct sfc_adapter_shared * 292 sfc_adapter_shared_by_eth_dev(struct rte_eth_dev *eth_dev) 293 { 294 struct sfc_adapter_shared *sas = eth_dev->data->dev_private; 295 296 return sas; 297 } 298 299 static inline struct sfc_adapter * 300 sfc_adapter_by_eth_dev(struct rte_eth_dev *eth_dev) 301 { 302 struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(eth_dev); 303 304 SFC_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); 305 306 return container_of(sap, struct sfc_adapter, priv); 307 } 308 309 static inline struct sfc_adapter_shared * 310 sfc_sa2shared(struct sfc_adapter *sa) 311 { 312 return sa->priv.shared; 313 } 314 315 /* 316 * Add wrapper functions to acquire/release lock to be able to remove or 317 * change the lock in one place. 318 */ 319 320 static inline void 321 sfc_adapter_lock_init(struct sfc_adapter *sa) 322 { 323 rte_spinlock_init(&sa->lock); 324 } 325 326 static inline int 327 sfc_adapter_is_locked(struct sfc_adapter *sa) 328 { 329 return rte_spinlock_is_locked(&sa->lock); 330 } 331 332 static inline void 333 sfc_adapter_lock(struct sfc_adapter *sa) 334 { 335 rte_spinlock_lock(&sa->lock); 336 } 337 338 static inline int 339 sfc_adapter_trylock(struct sfc_adapter *sa) 340 { 341 return rte_spinlock_trylock(&sa->lock); 342 } 343 344 static inline void 345 sfc_adapter_unlock(struct sfc_adapter *sa) 346 { 347 rte_spinlock_unlock(&sa->lock); 348 } 349 350 static inline void 351 sfc_adapter_lock_fini(__rte_unused struct sfc_adapter *sa) 352 { 353 /* Just for symmetry of the API */ 354 } 355 356 /** Get the number of milliseconds since boot from the default timer */ 357 static inline uint64_t 358 sfc_get_system_msecs(void) 359 { 360 return rte_get_timer_cycles() * MS_PER_S / rte_get_timer_hz(); 361 } 362 363 int sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id, 364 size_t len, int socket_id, efsys_mem_t *esmp); 365 void sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp); 366 367 uint32_t sfc_register_logtype(const struct rte_pci_addr *pci_addr, 368 const char *lt_prefix_str, 369 uint32_t ll_default); 370 371 int sfc_probe(struct sfc_adapter *sa); 372 void sfc_unprobe(struct sfc_adapter *sa); 373 int sfc_attach(struct sfc_adapter *sa); 374 void sfc_detach(struct sfc_adapter *sa); 375 int sfc_start(struct sfc_adapter *sa); 376 void sfc_stop(struct sfc_adapter *sa); 377 378 void sfc_schedule_restart(struct sfc_adapter *sa); 379 380 int sfc_mcdi_init(struct sfc_adapter *sa); 381 void sfc_mcdi_fini(struct sfc_adapter *sa); 382 383 int sfc_configure(struct sfc_adapter *sa); 384 void sfc_close(struct sfc_adapter *sa); 385 386 int sfc_intr_attach(struct sfc_adapter *sa); 387 void sfc_intr_detach(struct sfc_adapter *sa); 388 int sfc_intr_configure(struct sfc_adapter *sa); 389 void sfc_intr_close(struct sfc_adapter *sa); 390 int sfc_intr_start(struct sfc_adapter *sa); 391 void sfc_intr_stop(struct sfc_adapter *sa); 392 393 int sfc_port_attach(struct sfc_adapter *sa); 394 void sfc_port_detach(struct sfc_adapter *sa); 395 int sfc_port_configure(struct sfc_adapter *sa); 396 void sfc_port_close(struct sfc_adapter *sa); 397 int sfc_port_start(struct sfc_adapter *sa); 398 void sfc_port_stop(struct sfc_adapter *sa); 399 void sfc_port_link_mode_to_info(efx_link_mode_t link_mode, 400 struct rte_eth_link *link_info); 401 int sfc_port_update_mac_stats(struct sfc_adapter *sa); 402 int sfc_port_reset_mac_stats(struct sfc_adapter *sa); 403 int sfc_set_rx_mode(struct sfc_adapter *sa); 404 int sfc_set_rx_mode_unchecked(struct sfc_adapter *sa); 405 406 struct sfc_hw_switch_id; 407 408 int sfc_hw_switch_id_init(struct sfc_adapter *sa, 409 struct sfc_hw_switch_id **idp); 410 void sfc_hw_switch_id_fini(struct sfc_adapter *sa, 411 struct sfc_hw_switch_id *idp); 412 bool sfc_hw_switch_ids_equal(const struct sfc_hw_switch_id *left, 413 const struct sfc_hw_switch_id *right); 414 415 #ifdef __cplusplus 416 } 417 #endif 418 419 #endif /* _SFC_H */ 420