xref: /openbmc/linux/drivers/net/ethernet/sfc/siena/efx.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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