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