1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2874aeea5SJeff Kirsher /****************************************************************************
3f7a6d2c4SBen Hutchings * Driver for Solarflare network controllers and boards
4874aeea5SJeff Kirsher * Copyright 2005-2006 Fen Systems Ltd.
5f7a6d2c4SBen Hutchings * Copyright 2006-2013 Solarflare Communications Inc.
6874aeea5SJeff Kirsher */
7874aeea5SJeff Kirsher
8874aeea5SJeff Kirsher #ifndef EFX_EFX_H
9874aeea5SJeff Kirsher #define EFX_EFX_H
10874aeea5SJeff Kirsher
1151b35a45SEdward Cree #include <linux/indirect_call_wrapper.h>
12874aeea5SJeff Kirsher #include "net_driver.h"
1351b35a45SEdward Cree #include "ef100_rx.h"
1451b35a45SEdward Cree #include "ef100_tx.h"
15*84e7fc25SEdward Cree #include "efx_common.h"
16874aeea5SJeff Kirsher #include "filter.h"
17874aeea5SJeff Kirsher
18e340be92SShradha Shah int efx_net_open(struct net_device *net_dev);
19e340be92SShradha Shah int efx_net_stop(struct net_device *net_dev);
20e340be92SShradha Shah
21874aeea5SJeff Kirsher /* TX */
2200aef986SJoe Perches void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue);
2300aef986SJoe Perches netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
2400aef986SJoe Perches struct net_device *net_dev);
2551b35a45SEdward Cree netdev_tx_t __efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
efx_enqueue_skb(struct efx_tx_queue * tx_queue,struct sk_buff * skb)2651b35a45SEdward Cree static inline netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
2751b35a45SEdward Cree {
2851b35a45SEdward Cree return INDIRECT_CALL_2(tx_queue->efx->type->tx_enqueue,
2951b35a45SEdward Cree ef100_enqueue_skb, __efx_enqueue_skb,
3051b35a45SEdward Cree tx_queue, skb);
3151b35a45SEdward Cree }
323b4f06c7STom Zhao void efx_xmit_done_single(struct efx_tx_queue *tx_queue);
33183233beSBen Hutchings extern unsigned int efx_piobuf_size;
34874aeea5SJeff Kirsher
35874aeea5SJeff Kirsher /* RX */
3600aef986SJoe Perches void __efx_rx_packet(struct efx_channel *channel);
3700aef986SJoe Perches void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
3800aef986SJoe Perches unsigned int n_frags, unsigned int len, u16 flags);
efx_rx_flush_packet(struct efx_channel * channel)39ff734ef4SBen Hutchings static inline void efx_rx_flush_packet(struct efx_channel *channel)
40ff734ef4SBen Hutchings {
4185740cdfSBen Hutchings if (channel->rx_pkt_n_frags)
4251b35a45SEdward Cree INDIRECT_CALL_2(channel->efx->type->rx_packet,
4351b35a45SEdward Cree __ef100_rx_packet, __efx_rx_packet,
4451b35a45SEdward Cree channel);
45ff734ef4SBen Hutchings }
efx_rx_buf_hash_valid(struct efx_nic * efx,const u8 * prefix)4606888543SEdward Cree static inline bool efx_rx_buf_hash_valid(struct efx_nic *efx, const u8 *prefix)
4706888543SEdward Cree {
4806888543SEdward Cree if (efx->type->rx_buf_hash_valid)
4906888543SEdward Cree return INDIRECT_CALL_1(efx->type->rx_buf_hash_valid,
5006888543SEdward Cree ef100_rx_buf_hash_valid,
5106888543SEdward Cree prefix);
5206888543SEdward Cree return true;
5306888543SEdward Cree }
54874aeea5SJeff Kirsher
557e6d06f0SBen Hutchings /* Maximum number of TCP segments we support for soft-TSO */
567e6d06f0SBen Hutchings #define EFX_TSO_MAX_SEGS 100
577e6d06f0SBen Hutchings
587e6d06f0SBen Hutchings /* The smallest [rt]xq_entries that the driver supports. RX minimum
597e6d06f0SBen Hutchings * is a bit arbitrary. For TX, we must have space for at least 2
607e6d06f0SBen Hutchings * TSO skbs.
617e6d06f0SBen Hutchings */
627e6d06f0SBen Hutchings #define EFX_RXQ_MIN_ENT 128U
637e6d06f0SBen Hutchings #define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx))
64874aeea5SJeff Kirsher
65a53d26ebSBert Kenward /* All EF10 architecture NICs steal one bit of the DMAQ size for various
66a53d26ebSBert Kenward * other purposes when counting TxQ entries, so we halve the queue size.
67a53d26ebSBert Kenward */
68a53d26ebSBert Kenward #define EFX_TXQ_MAX_ENT(efx) (EFX_WORKAROUND_EF10(efx) ? \
69d9317aeaSBen Hutchings EFX_MAX_DMAQ_SIZE / 2 : EFX_MAX_DMAQ_SIZE)
70d9317aeaSBen Hutchings
efx_rss_enabled(struct efx_nic * efx)71f1c2ef40SBert Kenward static inline bool efx_rss_enabled(struct efx_nic *efx)
72f1c2ef40SBert Kenward {
73f1c2ef40SBert Kenward return efx->rss_spread > 1;
74f1c2ef40SBert Kenward }
75f1c2ef40SBert Kenward
76874aeea5SJeff Kirsher /* Filters */
77add72477SBen Hutchings
78add72477SBen Hutchings /**
79add72477SBen Hutchings * efx_filter_insert_filter - add or replace a filter
80add72477SBen Hutchings * @efx: NIC in which to insert the filter
81add72477SBen Hutchings * @spec: Specification for the filter
82add72477SBen Hutchings * @replace_equal: Flag for whether the specified filter may replace an
83add72477SBen Hutchings * existing filter with equal priority
84add72477SBen Hutchings *
85add72477SBen Hutchings * On success, return the filter ID.
86add72477SBen Hutchings * On failure, return a negative error code.
87add72477SBen Hutchings *
88b883d0bdSBen Hutchings * If existing filters have equal match values to the new filter spec,
89b883d0bdSBen Hutchings * then the new filter might replace them or the function might fail,
90b883d0bdSBen Hutchings * as follows.
91b883d0bdSBen Hutchings *
92b883d0bdSBen Hutchings * 1. If the existing filters have lower priority, or @replace_equal
93b883d0bdSBen Hutchings * is set and they have equal priority, replace them.
94b883d0bdSBen Hutchings *
95b883d0bdSBen Hutchings * 2. If the existing filters have higher priority, return -%EPERM.
96b883d0bdSBen Hutchings *
97b883d0bdSBen Hutchings * 3. If !efx_filter_is_mc_recipient(@spec), or the NIC does not
98b883d0bdSBen Hutchings * support delivery to multiple recipients, return -%EEXIST.
99b883d0bdSBen Hutchings *
100b883d0bdSBen Hutchings * This implies that filters for multiple multicast recipients must
101b883d0bdSBen Hutchings * all be inserted with the same priority and @replace_equal = %false.
102add72477SBen Hutchings */
efx_filter_insert_filter(struct efx_nic * efx,struct efx_filter_spec * spec,bool replace_equal)103add72477SBen Hutchings static inline s32 efx_filter_insert_filter(struct efx_nic *efx,
104874aeea5SJeff Kirsher struct efx_filter_spec *spec,
105add72477SBen Hutchings bool replace_equal)
106add72477SBen Hutchings {
107add72477SBen Hutchings return efx->type->filter_insert(efx, spec, replace_equal);
108add72477SBen Hutchings }
109add72477SBen Hutchings
110add72477SBen Hutchings /**
111add72477SBen Hutchings * efx_filter_remove_id_safe - remove a filter by ID, carefully
112add72477SBen Hutchings * @efx: NIC from which to remove the filter
113add72477SBen Hutchings * @priority: Priority of filter, as passed to @efx_filter_insert_filter
114add72477SBen Hutchings * @filter_id: ID of filter, as returned by @efx_filter_insert_filter
115add72477SBen Hutchings *
116add72477SBen Hutchings * This function will range-check @filter_id, so it is safe to call
117add72477SBen Hutchings * with a value passed from userland.
118add72477SBen Hutchings */
efx_filter_remove_id_safe(struct efx_nic * efx,enum efx_filter_priority priority,u32 filter_id)119add72477SBen Hutchings static inline int efx_filter_remove_id_safe(struct efx_nic *efx,
1201a6281acSBen Hutchings enum efx_filter_priority priority,
121add72477SBen Hutchings u32 filter_id)
122add72477SBen Hutchings {
123add72477SBen Hutchings return efx->type->filter_remove_safe(efx, priority, filter_id);
124add72477SBen Hutchings }
125add72477SBen Hutchings
126add72477SBen Hutchings /**
127add72477SBen Hutchings * efx_filter_get_filter_safe - retrieve a filter by ID, carefully
128add72477SBen Hutchings * @efx: NIC from which to remove the filter
129add72477SBen Hutchings * @priority: Priority of filter, as passed to @efx_filter_insert_filter
130add72477SBen Hutchings * @filter_id: ID of filter, as returned by @efx_filter_insert_filter
131add72477SBen Hutchings * @spec: Buffer in which to store filter specification
132add72477SBen Hutchings *
133add72477SBen Hutchings * This function will range-check @filter_id, so it is safe to call
134add72477SBen Hutchings * with a value passed from userland.
135add72477SBen Hutchings */
136add72477SBen Hutchings 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)137add72477SBen Hutchings efx_filter_get_filter_safe(struct efx_nic *efx,
1381a6281acSBen Hutchings enum efx_filter_priority priority,
139add72477SBen Hutchings u32 filter_id, struct efx_filter_spec *spec)
140add72477SBen Hutchings {
141add72477SBen Hutchings return efx->type->filter_get_safe(efx, priority, filter_id, spec);
142add72477SBen Hutchings }
143add72477SBen Hutchings
efx_filter_count_rx_used(struct efx_nic * efx,enum efx_filter_priority priority)144add72477SBen Hutchings static inline u32 efx_filter_count_rx_used(struct efx_nic *efx,
145add72477SBen Hutchings enum efx_filter_priority priority)
146add72477SBen Hutchings {
147add72477SBen Hutchings return efx->type->filter_count_rx_used(efx, priority);
148add72477SBen Hutchings }
efx_filter_get_rx_id_limit(struct efx_nic * efx)149add72477SBen Hutchings static inline u32 efx_filter_get_rx_id_limit(struct efx_nic *efx)
150add72477SBen Hutchings {
151add72477SBen Hutchings return efx->type->filter_get_rx_id_limit(efx);
152add72477SBen Hutchings }
efx_filter_get_rx_ids(struct efx_nic * efx,enum efx_filter_priority priority,u32 * buf,u32 size)153add72477SBen Hutchings static inline s32 efx_filter_get_rx_ids(struct efx_nic *efx,
1541a6281acSBen Hutchings enum efx_filter_priority priority,
155add72477SBen Hutchings u32 *buf, u32 size)
156add72477SBen Hutchings {
157add72477SBen Hutchings return efx->type->filter_get_rx_ids(efx, priority, buf, size);
158add72477SBen Hutchings }
159f8d62037SEdward Cree
16042356d9aSEdward Cree /* RSS contexts */
efx_rss_active(struct efx_rss_context * ctx)16142356d9aSEdward Cree static inline bool efx_rss_active(struct efx_rss_context *ctx)
16242356d9aSEdward Cree {
163f7226e0fSAlex Maftei (amaftei) return ctx->context_id != EFX_MCDI_RSS_CONTEXT_INVALID;
16442356d9aSEdward Cree }
16542356d9aSEdward Cree
166874aeea5SJeff Kirsher /* Ethtool support */
167874aeea5SJeff Kirsher extern const struct ethtool_ops efx_ethtool_ops;
168874aeea5SJeff Kirsher
169874aeea5SJeff Kirsher /* Global */
170539de7c5SBert Kenward unsigned int efx_usecs_to_ticks(struct efx_nic *efx, unsigned int usecs);
171539de7c5SBert Kenward unsigned int efx_ticks_to_usecs(struct efx_nic *efx, unsigned int ticks);
17200aef986SJoe Perches int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
1739e393b30SBen Hutchings unsigned int rx_usecs, bool rx_adaptive,
1749e393b30SBen Hutchings bool rx_may_override_tx);
17500aef986SJoe Perches void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
176a0c4faf5SBen Hutchings unsigned int *rx_usecs, bool *rx_adaptive);
177874aeea5SJeff Kirsher
178e4d112e4SEdward Cree /* Update the generic software stats in the passed stats array */
179e4d112e4SEdward Cree void efx_update_sw_stats(struct efx_nic *efx, u64 *stats);
180e4d112e4SEdward Cree
181874aeea5SJeff Kirsher /* MTD */
182874aeea5SJeff Kirsher #ifdef CONFIG_SFC_MTD
18300aef986SJoe Perches int efx_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts,
18445a3fd55SBen Hutchings size_t n_parts, size_t sizeof_part);
efx_mtd_probe(struct efx_nic * efx)18545a3fd55SBen Hutchings static inline int efx_mtd_probe(struct efx_nic *efx)
18645a3fd55SBen Hutchings {
18745a3fd55SBen Hutchings return efx->type->mtd_probe(efx);
18845a3fd55SBen Hutchings }
18900aef986SJoe Perches void efx_mtd_rename(struct efx_nic *efx);
19000aef986SJoe Perches void efx_mtd_remove(struct efx_nic *efx);
191874aeea5SJeff Kirsher #else
efx_mtd_probe(struct efx_nic * efx)192874aeea5SJeff Kirsher static inline int efx_mtd_probe(struct efx_nic *efx) { return 0; }
efx_mtd_rename(struct efx_nic * efx)193874aeea5SJeff Kirsher static inline void efx_mtd_rename(struct efx_nic *efx) {}
efx_mtd_remove(struct efx_nic * efx)194874aeea5SJeff Kirsher static inline void efx_mtd_remove(struct efx_nic *efx) {}
195874aeea5SJeff Kirsher #endif
196874aeea5SJeff Kirsher
1977fa8d547SShradha Shah #ifdef CONFIG_SFC_SRIOV
efx_vf_size(struct efx_nic * efx)1987fa8d547SShradha Shah static inline unsigned int efx_vf_size(struct efx_nic *efx)
1997fa8d547SShradha Shah {
2007fa8d547SShradha Shah return 1 << efx->vi_scale;
2017fa8d547SShradha Shah }
2027fa8d547SShradha Shah #endif
2037fa8d547SShradha Shah
efx_device_detach_sync(struct efx_nic * efx)204c2f3b8e3SDaniel Pieczko static inline void efx_device_detach_sync(struct efx_nic *efx)
205c2f3b8e3SDaniel Pieczko {
206c2f3b8e3SDaniel Pieczko struct net_device *dev = efx->net_dev;
207c2f3b8e3SDaniel Pieczko
208*84e7fc25SEdward Cree /* We must stop reps (which use our TX) before we stop ourselves. */
209*84e7fc25SEdward Cree efx_detach_reps(efx);
210*84e7fc25SEdward Cree
211c2f3b8e3SDaniel Pieczko /* Lock/freeze all TX queues so that we can be sure the
212c2f3b8e3SDaniel Pieczko * TX scheduler is stopped when we're done and before
213c2f3b8e3SDaniel Pieczko * netif_device_present() becomes false.
214c2f3b8e3SDaniel Pieczko */
21535205b21SBen Hutchings netif_tx_lock_bh(dev);
216c2f3b8e3SDaniel Pieczko netif_device_detach(dev);
21735205b21SBen Hutchings netif_tx_unlock_bh(dev);
218c2f3b8e3SDaniel Pieczko }
219c2f3b8e3SDaniel Pieczko
efx_device_attach_if_not_resetting(struct efx_nic * efx)2209c568fd8SPeter Dunning static inline void efx_device_attach_if_not_resetting(struct efx_nic *efx)
2219c568fd8SPeter Dunning {
222*84e7fc25SEdward Cree if ((efx->state != STATE_DISABLED) && !efx->reset_pending) {
2239c568fd8SPeter Dunning netif_device_attach(efx->net_dev);
224*84e7fc25SEdward Cree if (efx->state == STATE_NET_UP)
225*84e7fc25SEdward Cree efx_attach_reps(efx);
226*84e7fc25SEdward Cree }
2279c568fd8SPeter Dunning }
2289c568fd8SPeter Dunning
efx_rwsem_assert_write_locked(struct rw_semaphore * sem)229dd98708cSEdward Cree static inline bool efx_rwsem_assert_write_locked(struct rw_semaphore *sem)
230dd98708cSEdward Cree {
231dd98708cSEdward Cree if (WARN_ON(down_read_trylock(sem))) {
232dd98708cSEdward Cree up_read(sem);
233dd98708cSEdward Cree return false;
234dd98708cSEdward Cree }
235dd98708cSEdward Cree return true;
236dd98708cSEdward Cree }
237dd98708cSEdward Cree
238dfe44c1fSCharles McLachlan int efx_xdp_tx_buffers(struct efx_nic *efx, int n, struct xdp_frame **xdpfs,
239dfe44c1fSCharles McLachlan bool flush);
240dfe44c1fSCharles McLachlan
241874aeea5SJeff Kirsher #endif /* EFX_EFX_H */
242