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