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