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 }; 112 113 struct sfc_rxq_info; 114 struct sfc_txq_info; 115 struct sfc_dp_rx; 116 117 struct sfc_port { 118 unsigned int lsc_seq; 119 120 uint32_t phy_adv_cap_mask; 121 uint32_t phy_adv_cap; 122 123 unsigned int flow_ctrl; 124 boolean_t flow_ctrl_autoneg; 125 size_t pdu; 126 127 /* 128 * Flow API isolated mode overrides promisc and allmulti settings; 129 * they won't be applied if isolated mode is active 130 */ 131 boolean_t isolated; 132 boolean_t promisc; 133 boolean_t allmulti; 134 135 struct ether_addr default_mac_addr; 136 137 unsigned int max_mcast_addrs; 138 unsigned int nb_mcast_addrs; 139 uint8_t *mcast_addrs; 140 141 rte_spinlock_t mac_stats_lock; 142 uint64_t *mac_stats_buf; 143 unsigned int mac_stats_nb_supported; 144 efsys_mem_t mac_stats_dma_mem; 145 boolean_t mac_stats_reset_pending; 146 uint16_t mac_stats_update_period_ms; 147 uint32_t mac_stats_update_generation; 148 boolean_t mac_stats_periodic_dma_supported; 149 uint64_t mac_stats_last_request_timestamp; 150 151 uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES]; 152 153 uint64_t ipackets; 154 }; 155 156 struct sfc_rss_hf_rte_to_efx { 157 uint64_t rte; 158 efx_rx_hash_type_t efx; 159 }; 160 161 struct sfc_rss { 162 unsigned int channels; 163 efx_rx_scale_context_type_t context_type; 164 efx_rx_hash_support_t hash_support; 165 efx_rx_hash_alg_t hash_alg; 166 unsigned int hf_map_nb_entries; 167 struct sfc_rss_hf_rte_to_efx *hf_map; 168 169 efx_rx_hash_type_t hash_types; 170 unsigned int tbl[EFX_RSS_TBL_SIZE]; 171 uint8_t key[EFX_RSS_KEY_SIZE]; 172 }; 173 174 /* Adapter private data */ 175 struct sfc_adapter { 176 /* 177 * PMD setup and configuration is not thread safe. Since it is not 178 * performance sensitive, it is better to guarantee thread-safety 179 * and add device level lock. Adapter control operations which 180 * change its state should acquire the lock. 181 */ 182 rte_spinlock_t lock; 183 enum sfc_adapter_state state; 184 struct rte_pci_addr pci_addr; 185 uint16_t port_id; 186 struct rte_eth_dev *eth_dev; 187 struct rte_kvargs *kvargs; 188 uint32_t logtype_main; 189 int socket_id; 190 efsys_bar_t mem_bar; 191 efx_family_t family; 192 efx_nic_t *nic; 193 rte_spinlock_t nic_lock; 194 rte_atomic32_t restart_required; 195 196 struct sfc_mcdi mcdi; 197 struct sfc_intr intr; 198 struct sfc_port port; 199 struct sfc_filter filter; 200 201 unsigned int rxq_max; 202 unsigned int txq_max; 203 204 unsigned int txq_max_entries; 205 206 uint32_t evq_flags; 207 unsigned int evq_count; 208 209 unsigned int mgmt_evq_index; 210 /* 211 * The lock is used to serialise management event queue polling 212 * which can be done from different context. Also the lock 213 * guarantees that mgmt_evq_running is preserved while the lock 214 * is held. It is used to serialise polling and start/stop 215 * operations. 216 * 217 * Locks which may be held when the lock is acquired: 218 * - adapter lock, when: 219 * - device start/stop to change mgmt_evq_running 220 * - any control operations in client side MCDI proxy handling to 221 * poll management event queue waiting for proxy response 222 * - MCDI lock, when: 223 * - any control operations in client side MCDI proxy handling to 224 * poll management event queue waiting for proxy response 225 * 226 * Locks which are acquired with the lock held: 227 * - nic_lock, when: 228 * - MC event processing on management event queue polling 229 * (e.g. MC REBOOT or BADASSERT events) 230 */ 231 rte_spinlock_t mgmt_evq_lock; 232 bool mgmt_evq_running; 233 struct sfc_evq *mgmt_evq; 234 235 unsigned int rxq_count; 236 struct sfc_rxq_info *rxq_info; 237 238 unsigned int txq_count; 239 struct sfc_txq_info *txq_info; 240 241 boolean_t tso; 242 243 uint32_t rxd_wait_timeout_ns; 244 245 struct sfc_rss rss; 246 247 /* 248 * Shared memory copy of the Rx datapath name to be used by 249 * the secondary process to find Rx datapath to be used. 250 */ 251 char *dp_rx_name; 252 const struct sfc_dp_rx *dp_rx; 253 254 /* 255 * Shared memory copy of the Tx datapath name to be used by 256 * the secondary process to find Tx datapath to be used. 257 */ 258 char *dp_tx_name; 259 const struct sfc_dp_tx *dp_tx; 260 }; 261 262 /* 263 * Add wrapper functions to acquire/release lock to be able to remove or 264 * change the lock in one place. 265 */ 266 267 static inline void 268 sfc_adapter_lock_init(struct sfc_adapter *sa) 269 { 270 rte_spinlock_init(&sa->lock); 271 } 272 273 static inline int 274 sfc_adapter_is_locked(struct sfc_adapter *sa) 275 { 276 return rte_spinlock_is_locked(&sa->lock); 277 } 278 279 static inline void 280 sfc_adapter_lock(struct sfc_adapter *sa) 281 { 282 rte_spinlock_lock(&sa->lock); 283 } 284 285 static inline int 286 sfc_adapter_trylock(struct sfc_adapter *sa) 287 { 288 return rte_spinlock_trylock(&sa->lock); 289 } 290 291 static inline void 292 sfc_adapter_unlock(struct sfc_adapter *sa) 293 { 294 rte_spinlock_unlock(&sa->lock); 295 } 296 297 static inline void 298 sfc_adapter_lock_fini(__rte_unused struct sfc_adapter *sa) 299 { 300 /* Just for symmetry of the API */ 301 } 302 303 /** Get the number of milliseconds since boot from the default timer */ 304 static inline uint64_t 305 sfc_get_system_msecs(void) 306 { 307 return rte_get_timer_cycles() * MS_PER_S / rte_get_timer_hz(); 308 } 309 310 int sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id, 311 size_t len, int socket_id, efsys_mem_t *esmp); 312 void sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp); 313 314 uint32_t sfc_register_logtype(const struct rte_pci_addr *pci_addr, 315 const char *lt_prefix_str, 316 uint32_t ll_default); 317 318 int sfc_probe(struct sfc_adapter *sa); 319 void sfc_unprobe(struct sfc_adapter *sa); 320 int sfc_attach(struct sfc_adapter *sa); 321 void sfc_detach(struct sfc_adapter *sa); 322 int sfc_start(struct sfc_adapter *sa); 323 void sfc_stop(struct sfc_adapter *sa); 324 325 void sfc_schedule_restart(struct sfc_adapter *sa); 326 327 int sfc_mcdi_init(struct sfc_adapter *sa); 328 void sfc_mcdi_fini(struct sfc_adapter *sa); 329 330 int sfc_configure(struct sfc_adapter *sa); 331 void sfc_close(struct sfc_adapter *sa); 332 333 int sfc_intr_attach(struct sfc_adapter *sa); 334 void sfc_intr_detach(struct sfc_adapter *sa); 335 int sfc_intr_configure(struct sfc_adapter *sa); 336 void sfc_intr_close(struct sfc_adapter *sa); 337 int sfc_intr_start(struct sfc_adapter *sa); 338 void sfc_intr_stop(struct sfc_adapter *sa); 339 340 int sfc_port_attach(struct sfc_adapter *sa); 341 void sfc_port_detach(struct sfc_adapter *sa); 342 int sfc_port_configure(struct sfc_adapter *sa); 343 void sfc_port_close(struct sfc_adapter *sa); 344 int sfc_port_start(struct sfc_adapter *sa); 345 void sfc_port_stop(struct sfc_adapter *sa); 346 void sfc_port_link_mode_to_info(efx_link_mode_t link_mode, 347 struct rte_eth_link *link_info); 348 int sfc_port_update_mac_stats(struct sfc_adapter *sa); 349 int sfc_port_reset_mac_stats(struct sfc_adapter *sa); 350 int sfc_set_rx_mode(struct sfc_adapter *sa); 351 352 353 #ifdef __cplusplus 354 } 355 #endif 356 357 #endif /* _SFC_H */ 358