16e173d3bSMartin Habets /* SPDX-License-Identifier: GPL-2.0-only */
26e173d3bSMartin Habets /****************************************************************************
36e173d3bSMartin Habets * Driver for Solarflare network controllers and boards
46e173d3bSMartin Habets * Copyright 2005-2006 Fen Systems Ltd.
56e173d3bSMartin Habets * Copyright 2006-2013 Solarflare Communications Inc.
66e173d3bSMartin Habets */
76e173d3bSMartin Habets
86e173d3bSMartin Habets #ifndef EFX_EFX_H
96e173d3bSMartin Habets #define EFX_EFX_H
106e173d3bSMartin Habets
116e173d3bSMartin Habets #include <linux/indirect_call_wrapper.h>
126e173d3bSMartin Habets #include "net_driver.h"
136e173d3bSMartin Habets #include "filter.h"
146e173d3bSMartin Habets
156e173d3bSMartin Habets /* TX */
1671ad88f6SMartin Habets void efx_siena_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue);
1771ad88f6SMartin Habets netdev_tx_t efx_siena_hard_start_xmit(struct sk_buff *skb,
186e173d3bSMartin Habets struct net_device *net_dev);
1971ad88f6SMartin Habets netdev_tx_t __efx_siena_enqueue_skb(struct efx_tx_queue *tx_queue,
2071ad88f6SMartin Habets struct sk_buff *skb);
efx_enqueue_skb(struct efx_tx_queue * tx_queue,struct sk_buff * skb)216e173d3bSMartin Habets static inline netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
226e173d3bSMartin Habets {
23956f2d86SMartin Habets return INDIRECT_CALL_1(tx_queue->efx->type->tx_enqueue,
2471ad88f6SMartin Habets __efx_siena_enqueue_skb, tx_queue, skb);
256e173d3bSMartin Habets }
2671ad88f6SMartin Habets int efx_siena_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
276e173d3bSMartin Habets void *type_data);
286e173d3bSMartin Habets
296e173d3bSMartin Habets /* RX */
3071ad88f6SMartin Habets void __efx_siena_rx_packet(struct efx_channel *channel);
3171ad88f6SMartin Habets void efx_siena_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
326e173d3bSMartin Habets unsigned int n_frags, unsigned int len, u16 flags);
efx_rx_flush_packet(struct efx_channel * channel)336e173d3bSMartin Habets static inline void efx_rx_flush_packet(struct efx_channel *channel)
346e173d3bSMartin Habets {
356e173d3bSMartin Habets if (channel->rx_pkt_n_frags)
3671ad88f6SMartin Habets __efx_siena_rx_packet(channel);
376e173d3bSMartin Habets }
386e173d3bSMartin Habets
396e173d3bSMartin Habets /* Maximum number of TCP segments we support for soft-TSO */
406e173d3bSMartin Habets #define EFX_TSO_MAX_SEGS 100
416e173d3bSMartin Habets
426e173d3bSMartin Habets /* The smallest [rt]xq_entries that the driver supports. RX minimum
436e173d3bSMartin Habets * is a bit arbitrary. For TX, we must have space for at least 2
446e173d3bSMartin Habets * TSO skbs.
456e173d3bSMartin Habets */
466e173d3bSMartin Habets #define EFX_RXQ_MIN_ENT 128U
477f9e4b2aSMartin Habets #define EFX_TXQ_MIN_ENT(efx) (2 * efx_siena_tx_max_skb_descs(efx))
486e173d3bSMartin Habets
496e173d3bSMartin Habets /* All EF10 architecture NICs steal one bit of the DMAQ size for various
506e173d3bSMartin Habets * other purposes when counting TxQ entries, so we halve the queue size.
516e173d3bSMartin Habets */
526e173d3bSMartin Habets #define EFX_TXQ_MAX_ENT(efx) (EFX_WORKAROUND_EF10(efx) ? \
536e173d3bSMartin Habets EFX_MAX_DMAQ_SIZE / 2 : EFX_MAX_DMAQ_SIZE)
546e173d3bSMartin Habets
efx_rss_enabled(struct efx_nic * efx)556e173d3bSMartin Habets static inline bool efx_rss_enabled(struct efx_nic *efx)
566e173d3bSMartin Habets {
576e173d3bSMartin Habets return efx->rss_spread > 1;
586e173d3bSMartin Habets }
596e173d3bSMartin Habets
606e173d3bSMartin Habets /* Filters */
616e173d3bSMartin Habets
626e173d3bSMartin Habets /**
636e173d3bSMartin Habets * efx_filter_insert_filter - add or replace a filter
646e173d3bSMartin Habets * @efx: NIC in which to insert the filter
656e173d3bSMartin Habets * @spec: Specification for the filter
666e173d3bSMartin Habets * @replace_equal: Flag for whether the specified filter may replace an
676e173d3bSMartin Habets * existing filter with equal priority
686e173d3bSMartin Habets *
696e173d3bSMartin Habets * On success, return the filter ID.
706e173d3bSMartin Habets * On failure, return a negative error code.
716e173d3bSMartin Habets *
726e173d3bSMartin Habets * If existing filters have equal match values to the new filter spec,
736e173d3bSMartin Habets * then the new filter might replace them or the function might fail,
746e173d3bSMartin Habets * as follows.
756e173d3bSMartin Habets *
766e173d3bSMartin Habets * 1. If the existing filters have lower priority, or @replace_equal
776e173d3bSMartin Habets * is set and they have equal priority, replace them.
786e173d3bSMartin Habets *
796e173d3bSMartin Habets * 2. If the existing filters have higher priority, return -%EPERM.
806e173d3bSMartin Habets *
817f9e4b2aSMartin Habets * 3. If !efx_siena_filter_is_mc_recipient(@spec), or the NIC does not
826e173d3bSMartin Habets * support delivery to multiple recipients, return -%EEXIST.
836e173d3bSMartin Habets *
846e173d3bSMartin Habets * This implies that filters for multiple multicast recipients must
856e173d3bSMartin Habets * all be inserted with the same priority and @replace_equal = %false.
866e173d3bSMartin Habets */
efx_filter_insert_filter(struct efx_nic * efx,struct efx_filter_spec * spec,bool replace_equal)876e173d3bSMartin Habets static inline s32 efx_filter_insert_filter(struct efx_nic *efx,
886e173d3bSMartin Habets struct efx_filter_spec *spec,
896e173d3bSMartin Habets bool replace_equal)
906e173d3bSMartin Habets {
916e173d3bSMartin Habets return efx->type->filter_insert(efx, spec, replace_equal);
926e173d3bSMartin Habets }
936e173d3bSMartin Habets
946e173d3bSMartin Habets /**
956e173d3bSMartin Habets * efx_filter_remove_id_safe - remove a filter by ID, carefully
966e173d3bSMartin Habets * @efx: NIC from which to remove the filter
976e173d3bSMartin Habets * @priority: Priority of filter, as passed to @efx_filter_insert_filter
986e173d3bSMartin Habets * @filter_id: ID of filter, as returned by @efx_filter_insert_filter
996e173d3bSMartin Habets *
1006e173d3bSMartin Habets * This function will range-check @filter_id, so it is safe to call
1016e173d3bSMartin Habets * with a value passed from userland.
1026e173d3bSMartin Habets */
efx_filter_remove_id_safe(struct efx_nic * efx,enum efx_filter_priority priority,u32 filter_id)1036e173d3bSMartin Habets static inline int efx_filter_remove_id_safe(struct efx_nic *efx,
1046e173d3bSMartin Habets enum efx_filter_priority priority,
1056e173d3bSMartin Habets u32 filter_id)
1066e173d3bSMartin Habets {
1076e173d3bSMartin Habets return efx->type->filter_remove_safe(efx, priority, filter_id);
1086e173d3bSMartin Habets }
1096e173d3bSMartin Habets
1106e173d3bSMartin Habets /**
1116e173d3bSMartin Habets * efx_filter_get_filter_safe - retrieve a filter by ID, carefully
1126e173d3bSMartin Habets * @efx: NIC from which to remove the filter
1136e173d3bSMartin Habets * @priority: Priority of filter, as passed to @efx_filter_insert_filter
1146e173d3bSMartin Habets * @filter_id: ID of filter, as returned by @efx_filter_insert_filter
1156e173d3bSMartin Habets * @spec: Buffer in which to store filter specification
1166e173d3bSMartin Habets *
1176e173d3bSMartin Habets * This function will range-check @filter_id, so it is safe to call
1186e173d3bSMartin Habets * with a value passed from userland.
1196e173d3bSMartin Habets */
1206e173d3bSMartin Habets static inline int
efx_filter_get_filter_safe(struct efx_nic * efx,enum efx_filter_priority priority,u32 filter_id,struct efx_filter_spec * spec)1216e173d3bSMartin Habets efx_filter_get_filter_safe(struct efx_nic *efx,
1226e173d3bSMartin Habets enum efx_filter_priority priority,
1236e173d3bSMartin Habets u32 filter_id, struct efx_filter_spec *spec)
1246e173d3bSMartin Habets {
1256e173d3bSMartin Habets return efx->type->filter_get_safe(efx, priority, filter_id, spec);
1266e173d3bSMartin Habets }
1276e173d3bSMartin Habets
efx_filter_count_rx_used(struct efx_nic * efx,enum efx_filter_priority priority)1286e173d3bSMartin Habets static inline u32 efx_filter_count_rx_used(struct efx_nic *efx,
1296e173d3bSMartin Habets enum efx_filter_priority priority)
1306e173d3bSMartin Habets {
1316e173d3bSMartin Habets return efx->type->filter_count_rx_used(efx, priority);
1326e173d3bSMartin Habets }
efx_filter_get_rx_id_limit(struct efx_nic * efx)1336e173d3bSMartin Habets static inline u32 efx_filter_get_rx_id_limit(struct efx_nic *efx)
1346e173d3bSMartin Habets {
1356e173d3bSMartin Habets return efx->type->filter_get_rx_id_limit(efx);
1366e173d3bSMartin Habets }
efx_filter_get_rx_ids(struct efx_nic * efx,enum efx_filter_priority priority,u32 * buf,u32 size)1376e173d3bSMartin Habets static inline s32 efx_filter_get_rx_ids(struct efx_nic *efx,
1386e173d3bSMartin Habets enum efx_filter_priority priority,
1396e173d3bSMartin Habets u32 *buf, u32 size)
1406e173d3bSMartin Habets {
1416e173d3bSMartin Habets return efx->type->filter_get_rx_ids(efx, priority, buf, size);
1426e173d3bSMartin Habets }
1436e173d3bSMartin Habets
1446e173d3bSMartin Habets /* RSS contexts */
efx_rss_active(struct efx_rss_context * ctx)1456e173d3bSMartin Habets static inline bool efx_rss_active(struct efx_rss_context *ctx)
1466e173d3bSMartin Habets {
1476e173d3bSMartin Habets return ctx->context_id != EFX_MCDI_RSS_CONTEXT_INVALID;
1486e173d3bSMartin Habets }
1496e173d3bSMartin Habets
1506e173d3bSMartin Habets /* Ethtool support */
15171ad88f6SMartin Habets extern const struct ethtool_ops efx_siena_ethtool_ops;
1526e173d3bSMartin Habets
1536e173d3bSMartin Habets /* Global */
15471ad88f6SMartin Habets unsigned int efx_siena_usecs_to_ticks(struct efx_nic *efx, unsigned int usecs);
15571ad88f6SMartin Habets int efx_siena_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
1566e173d3bSMartin Habets unsigned int rx_usecs, bool rx_adaptive,
1576e173d3bSMartin Habets bool rx_may_override_tx);
15871ad88f6SMartin Habets void efx_siena_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
1596e173d3bSMartin Habets unsigned int *rx_usecs, bool *rx_adaptive);
1606e173d3bSMartin Habets
1616e173d3bSMartin Habets /* Update the generic software stats in the passed stats array */
16271ad88f6SMartin Habets void efx_siena_update_sw_stats(struct efx_nic *efx, u64 *stats);
1636e173d3bSMartin Habets
1646e173d3bSMartin Habets /* MTD */
16565d4b471SMartin Habets #ifdef CONFIG_SFC_SIENA_MTD
16671ad88f6SMartin Habets int efx_siena_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts,
1676e173d3bSMartin Habets size_t n_parts, size_t sizeof_part);
efx_mtd_probe(struct efx_nic * efx)1686e173d3bSMartin Habets static inline int efx_mtd_probe(struct efx_nic *efx)
1696e173d3bSMartin Habets {
1706e173d3bSMartin Habets return efx->type->mtd_probe(efx);
1716e173d3bSMartin Habets }
17271ad88f6SMartin Habets void efx_siena_mtd_rename(struct efx_nic *efx);
17371ad88f6SMartin Habets void efx_siena_mtd_remove(struct efx_nic *efx);
1746e173d3bSMartin Habets #else
efx_mtd_probe(struct efx_nic * efx)1756e173d3bSMartin Habets static inline int efx_mtd_probe(struct efx_nic *efx) { return 0; }
efx_siena_mtd_rename(struct efx_nic * efx)17671ad88f6SMartin Habets static inline void efx_siena_mtd_rename(struct efx_nic *efx) {}
efx_siena_mtd_remove(struct efx_nic * efx)17771ad88f6SMartin Habets static inline void efx_siena_mtd_remove(struct efx_nic *efx) {}
1786e173d3bSMartin Habets #endif
1796e173d3bSMartin Habets
180*dfb1cfbdSMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV
efx_vf_size(struct efx_nic * efx)1816e173d3bSMartin Habets static inline unsigned int efx_vf_size(struct efx_nic *efx)
1826e173d3bSMartin Habets {
1836e173d3bSMartin Habets return 1 << efx->vi_scale;
1846e173d3bSMartin Habets }
1856e173d3bSMartin Habets #endif
1866e173d3bSMartin Habets
efx_device_detach_sync(struct efx_nic * efx)1876e173d3bSMartin Habets static inline void efx_device_detach_sync(struct efx_nic *efx)
1886e173d3bSMartin Habets {
1896e173d3bSMartin Habets struct net_device *dev = efx->net_dev;
1906e173d3bSMartin Habets
1916e173d3bSMartin Habets /* Lock/freeze all TX queues so that we can be sure the
1926e173d3bSMartin Habets * TX scheduler is stopped when we're done and before
1936e173d3bSMartin Habets * netif_device_present() becomes false.
1946e173d3bSMartin Habets */
1956e173d3bSMartin Habets netif_tx_lock_bh(dev);
1966e173d3bSMartin Habets netif_device_detach(dev);
1976e173d3bSMartin Habets netif_tx_unlock_bh(dev);
1986e173d3bSMartin Habets }
1996e173d3bSMartin Habets
efx_device_attach_if_not_resetting(struct efx_nic * efx)2006e173d3bSMartin Habets static inline void efx_device_attach_if_not_resetting(struct efx_nic *efx)
2016e173d3bSMartin Habets {
2026e173d3bSMartin Habets if ((efx->state != STATE_DISABLED) && !efx->reset_pending)
2036e173d3bSMartin Habets netif_device_attach(efx->net_dev);
2046e173d3bSMartin Habets }
2056e173d3bSMartin Habets
efx_rwsem_assert_write_locked(struct rw_semaphore * sem)2066e173d3bSMartin Habets static inline bool efx_rwsem_assert_write_locked(struct rw_semaphore *sem)
2076e173d3bSMartin Habets {
2086e173d3bSMartin Habets if (WARN_ON(down_read_trylock(sem))) {
2096e173d3bSMartin Habets up_read(sem);
2106e173d3bSMartin Habets return false;
2116e173d3bSMartin Habets }
2126e173d3bSMartin Habets return true;
2136e173d3bSMartin Habets }
2146e173d3bSMartin Habets
21571ad88f6SMartin Habets int efx_siena_xdp_tx_buffers(struct efx_nic *efx, int n,
21671ad88f6SMartin Habets struct xdp_frame **xdpfs, bool flush);
2176e173d3bSMartin Habets
2186e173d3bSMartin Habets #endif /* EFX_EFX_H */
219