dpdk/drivers/net/sfc/sfc.h
<<
>>
Prefs
   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
  34extern "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 */
  75enum 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
  88enum 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
  95struct 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
 102struct sfc_rxq;
 103struct sfc_txq;
 104
 105struct sfc_rxq_info;
 106struct sfc_txq_info;
 107struct sfc_dp_rx;
 108
 109struct 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
 147struct sfc_rss_hf_rte_to_efx {
 148        uint64_t                        rte;
 149        efx_rx_hash_type_t              efx;
 150};
 151
 152struct 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 */
 168struct 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 */
 189struct 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
 196static inline struct sfc_adapter_priv *
 197sfc_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 */
 206struct 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
 292static inline struct sfc_adapter_shared *
 293sfc_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
 300static inline struct sfc_adapter *
 301sfc_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
 310static inline struct sfc_adapter_shared *
 311sfc_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
 321static inline void
 322sfc_adapter_lock_init(struct sfc_adapter *sa)
 323{
 324        rte_spinlock_init(&sa->lock);
 325}
 326
 327static inline int
 328sfc_adapter_is_locked(struct sfc_adapter *sa)
 329{
 330        return rte_spinlock_is_locked(&sa->lock);
 331}
 332
 333static inline void
 334sfc_adapter_lock(struct sfc_adapter *sa)
 335{
 336        rte_spinlock_lock(&sa->lock);
 337}
 338
 339static inline int
 340sfc_adapter_trylock(struct sfc_adapter *sa)
 341{
 342        return rte_spinlock_trylock(&sa->lock);
 343}
 344
 345static inline void
 346sfc_adapter_unlock(struct sfc_adapter *sa)
 347{
 348        rte_spinlock_unlock(&sa->lock);
 349}
 350
 351static inline void
 352sfc_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 */
 358static inline uint64_t
 359sfc_get_system_msecs(void)
 360{
 361        return rte_get_timer_cycles() * MS_PER_S / rte_get_timer_hz();
 362}
 363
 364int 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);
 366void sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp);
 367
 368uint32_t sfc_register_logtype(const struct rte_pci_addr *pci_addr,
 369                              const char *lt_prefix_str,
 370                              uint32_t ll_default);
 371
 372int sfc_probe(struct sfc_adapter *sa);
 373void sfc_unprobe(struct sfc_adapter *sa);
 374int sfc_attach(struct sfc_adapter *sa);
 375void sfc_detach(struct sfc_adapter *sa);
 376int sfc_start(struct sfc_adapter *sa);
 377void sfc_stop(struct sfc_adapter *sa);
 378
 379void sfc_schedule_restart(struct sfc_adapter *sa);
 380
 381int sfc_mcdi_init(struct sfc_adapter *sa);
 382void sfc_mcdi_fini(struct sfc_adapter *sa);
 383
 384int sfc_configure(struct sfc_adapter *sa);
 385void sfc_close(struct sfc_adapter *sa);
 386
 387int sfc_intr_attach(struct sfc_adapter *sa);
 388void sfc_intr_detach(struct sfc_adapter *sa);
 389int sfc_intr_configure(struct sfc_adapter *sa);
 390void sfc_intr_close(struct sfc_adapter *sa);
 391int sfc_intr_start(struct sfc_adapter *sa);
 392void sfc_intr_stop(struct sfc_adapter *sa);
 393
 394int sfc_port_attach(struct sfc_adapter *sa);
 395void sfc_port_detach(struct sfc_adapter *sa);
 396int sfc_port_configure(struct sfc_adapter *sa);
 397void sfc_port_close(struct sfc_adapter *sa);
 398int sfc_port_start(struct sfc_adapter *sa);
 399void sfc_port_stop(struct sfc_adapter *sa);
 400void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
 401                                struct rte_eth_link *link_info);
 402int sfc_port_update_mac_stats(struct sfc_adapter *sa);
 403int sfc_port_reset_mac_stats(struct sfc_adapter *sa);
 404int sfc_set_rx_mode(struct sfc_adapter *sa);
 405int sfc_set_rx_mode_unchecked(struct sfc_adapter *sa);
 406
 407struct sfc_hw_switch_id;
 408
 409int sfc_hw_switch_id_init(struct sfc_adapter *sa,
 410                          struct sfc_hw_switch_id **idp);
 411void sfc_hw_switch_id_fini(struct sfc_adapter *sa,
 412                           struct sfc_hw_switch_id *idp);
 413bool 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