162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/**************************************************************************** 362306a36Sopenharmony_ci * Driver for Solarflare network controllers and boards 462306a36Sopenharmony_ci * Copyright 2005-2006 Fen Systems Ltd. 562306a36Sopenharmony_ci * Copyright 2006-2013 Solarflare Communications Inc. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef EF4_EFX_H 962306a36Sopenharmony_ci#define EF4_EFX_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include "net_driver.h" 1262306a36Sopenharmony_ci#include "filter.h" 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci/* All controllers use BAR 0 for I/O space and BAR 2(&3) for memory */ 1562306a36Sopenharmony_ci/* All VFs use BAR 0/1 for memory */ 1662306a36Sopenharmony_ci#define EF4_MEM_BAR 2 1762306a36Sopenharmony_ci#define EF4_MEM_VF_BAR 0 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ciint ef4_net_open(struct net_device *net_dev); 2062306a36Sopenharmony_ciint ef4_net_stop(struct net_device *net_dev); 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/* TX */ 2362306a36Sopenharmony_ciint ef4_probe_tx_queue(struct ef4_tx_queue *tx_queue); 2462306a36Sopenharmony_civoid ef4_remove_tx_queue(struct ef4_tx_queue *tx_queue); 2562306a36Sopenharmony_civoid ef4_init_tx_queue(struct ef4_tx_queue *tx_queue); 2662306a36Sopenharmony_civoid ef4_init_tx_queue_core_txq(struct ef4_tx_queue *tx_queue); 2762306a36Sopenharmony_civoid ef4_fini_tx_queue(struct ef4_tx_queue *tx_queue); 2862306a36Sopenharmony_cinetdev_tx_t ef4_hard_start_xmit(struct sk_buff *skb, 2962306a36Sopenharmony_ci struct net_device *net_dev); 3062306a36Sopenharmony_cinetdev_tx_t ef4_enqueue_skb(struct ef4_tx_queue *tx_queue, struct sk_buff *skb); 3162306a36Sopenharmony_civoid ef4_xmit_done(struct ef4_tx_queue *tx_queue, unsigned int index); 3262306a36Sopenharmony_ciint ef4_setup_tc(struct net_device *net_dev, enum tc_setup_type type, 3362306a36Sopenharmony_ci void *type_data); 3462306a36Sopenharmony_ciunsigned int ef4_tx_max_skb_descs(struct ef4_nic *efx); 3562306a36Sopenharmony_ciextern bool ef4_separate_tx_channels; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* RX */ 3862306a36Sopenharmony_civoid ef4_set_default_rx_indir_table(struct ef4_nic *efx); 3962306a36Sopenharmony_civoid ef4_rx_config_page_split(struct ef4_nic *efx); 4062306a36Sopenharmony_ciint ef4_probe_rx_queue(struct ef4_rx_queue *rx_queue); 4162306a36Sopenharmony_civoid ef4_remove_rx_queue(struct ef4_rx_queue *rx_queue); 4262306a36Sopenharmony_civoid ef4_init_rx_queue(struct ef4_rx_queue *rx_queue); 4362306a36Sopenharmony_civoid ef4_fini_rx_queue(struct ef4_rx_queue *rx_queue); 4462306a36Sopenharmony_civoid ef4_fast_push_rx_descriptors(struct ef4_rx_queue *rx_queue, bool atomic); 4562306a36Sopenharmony_civoid ef4_rx_slow_fill(struct timer_list *t); 4662306a36Sopenharmony_civoid __ef4_rx_packet(struct ef4_channel *channel); 4762306a36Sopenharmony_civoid ef4_rx_packet(struct ef4_rx_queue *rx_queue, unsigned int index, 4862306a36Sopenharmony_ci unsigned int n_frags, unsigned int len, u16 flags); 4962306a36Sopenharmony_cistatic inline void ef4_rx_flush_packet(struct ef4_channel *channel) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci if (channel->rx_pkt_n_frags) 5262306a36Sopenharmony_ci __ef4_rx_packet(channel); 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_civoid ef4_schedule_slow_fill(struct ef4_rx_queue *rx_queue); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define EF4_MAX_DMAQ_SIZE 4096UL 5762306a36Sopenharmony_ci#define EF4_DEFAULT_DMAQ_SIZE 1024UL 5862306a36Sopenharmony_ci#define EF4_MIN_DMAQ_SIZE 512UL 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci#define EF4_MAX_EVQ_SIZE 16384UL 6162306a36Sopenharmony_ci#define EF4_MIN_EVQ_SIZE 512UL 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/* Maximum number of TCP segments we support for soft-TSO */ 6462306a36Sopenharmony_ci#define EF4_TSO_MAX_SEGS 100 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* The smallest [rt]xq_entries that the driver supports. RX minimum 6762306a36Sopenharmony_ci * is a bit arbitrary. For TX, we must have space for at least 2 6862306a36Sopenharmony_ci * TSO skbs. 6962306a36Sopenharmony_ci */ 7062306a36Sopenharmony_ci#define EF4_RXQ_MIN_ENT 128U 7162306a36Sopenharmony_ci#define EF4_TXQ_MIN_ENT(efx) (2 * ef4_tx_max_skb_descs(efx)) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cistatic inline bool ef4_rss_enabled(struct ef4_nic *efx) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci return efx->rss_spread > 1; 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci/* Filters */ 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_civoid ef4_mac_reconfigure(struct ef4_nic *efx); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/** 8362306a36Sopenharmony_ci * ef4_filter_insert_filter - add or replace a filter 8462306a36Sopenharmony_ci * @efx: NIC in which to insert the filter 8562306a36Sopenharmony_ci * @spec: Specification for the filter 8662306a36Sopenharmony_ci * @replace_equal: Flag for whether the specified filter may replace an 8762306a36Sopenharmony_ci * existing filter with equal priority 8862306a36Sopenharmony_ci * 8962306a36Sopenharmony_ci * On success, return the filter ID. 9062306a36Sopenharmony_ci * On failure, return a negative error code. 9162306a36Sopenharmony_ci * 9262306a36Sopenharmony_ci * If existing filters have equal match values to the new filter spec, 9362306a36Sopenharmony_ci * then the new filter might replace them or the function might fail, 9462306a36Sopenharmony_ci * as follows. 9562306a36Sopenharmony_ci * 9662306a36Sopenharmony_ci * 1. If the existing filters have lower priority, or @replace_equal 9762306a36Sopenharmony_ci * is set and they have equal priority, replace them. 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * 2. If the existing filters have higher priority, return -%EPERM. 10062306a36Sopenharmony_ci * 10162306a36Sopenharmony_ci * 3. If !ef4_filter_is_mc_recipient(@spec), or the NIC does not 10262306a36Sopenharmony_ci * support delivery to multiple recipients, return -%EEXIST. 10362306a36Sopenharmony_ci * 10462306a36Sopenharmony_ci * This implies that filters for multiple multicast recipients must 10562306a36Sopenharmony_ci * all be inserted with the same priority and @replace_equal = %false. 10662306a36Sopenharmony_ci */ 10762306a36Sopenharmony_cistatic inline s32 ef4_filter_insert_filter(struct ef4_nic *efx, 10862306a36Sopenharmony_ci struct ef4_filter_spec *spec, 10962306a36Sopenharmony_ci bool replace_equal) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci return efx->type->filter_insert(efx, spec, replace_equal); 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci/** 11562306a36Sopenharmony_ci * ef4_filter_remove_id_safe - remove a filter by ID, carefully 11662306a36Sopenharmony_ci * @efx: NIC from which to remove the filter 11762306a36Sopenharmony_ci * @priority: Priority of filter, as passed to @ef4_filter_insert_filter 11862306a36Sopenharmony_ci * @filter_id: ID of filter, as returned by @ef4_filter_insert_filter 11962306a36Sopenharmony_ci * 12062306a36Sopenharmony_ci * This function will range-check @filter_id, so it is safe to call 12162306a36Sopenharmony_ci * with a value passed from userland. 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_cistatic inline int ef4_filter_remove_id_safe(struct ef4_nic *efx, 12462306a36Sopenharmony_ci enum ef4_filter_priority priority, 12562306a36Sopenharmony_ci u32 filter_id) 12662306a36Sopenharmony_ci{ 12762306a36Sopenharmony_ci return efx->type->filter_remove_safe(efx, priority, filter_id); 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci/** 13162306a36Sopenharmony_ci * ef4_filter_get_filter_safe - retrieve a filter by ID, carefully 13262306a36Sopenharmony_ci * @efx: NIC from which to remove the filter 13362306a36Sopenharmony_ci * @priority: Priority of filter, as passed to @ef4_filter_insert_filter 13462306a36Sopenharmony_ci * @filter_id: ID of filter, as returned by @ef4_filter_insert_filter 13562306a36Sopenharmony_ci * @spec: Buffer in which to store filter specification 13662306a36Sopenharmony_ci * 13762306a36Sopenharmony_ci * This function will range-check @filter_id, so it is safe to call 13862306a36Sopenharmony_ci * with a value passed from userland. 13962306a36Sopenharmony_ci */ 14062306a36Sopenharmony_cistatic inline int 14162306a36Sopenharmony_cief4_filter_get_filter_safe(struct ef4_nic *efx, 14262306a36Sopenharmony_ci enum ef4_filter_priority priority, 14362306a36Sopenharmony_ci u32 filter_id, struct ef4_filter_spec *spec) 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci return efx->type->filter_get_safe(efx, priority, filter_id, spec); 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic inline u32 ef4_filter_count_rx_used(struct ef4_nic *efx, 14962306a36Sopenharmony_ci enum ef4_filter_priority priority) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci return efx->type->filter_count_rx_used(efx, priority); 15262306a36Sopenharmony_ci} 15362306a36Sopenharmony_cistatic inline u32 ef4_filter_get_rx_id_limit(struct ef4_nic *efx) 15462306a36Sopenharmony_ci{ 15562306a36Sopenharmony_ci return efx->type->filter_get_rx_id_limit(efx); 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_cistatic inline s32 ef4_filter_get_rx_ids(struct ef4_nic *efx, 15862306a36Sopenharmony_ci enum ef4_filter_priority priority, 15962306a36Sopenharmony_ci u32 *buf, u32 size) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci return efx->type->filter_get_rx_ids(efx, priority, buf, size); 16262306a36Sopenharmony_ci} 16362306a36Sopenharmony_ci#ifdef CONFIG_RFS_ACCEL 16462306a36Sopenharmony_ciint ef4_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, 16562306a36Sopenharmony_ci u16 rxq_index, u32 flow_id); 16662306a36Sopenharmony_cibool __ef4_filter_rfs_expire(struct ef4_nic *efx, unsigned quota); 16762306a36Sopenharmony_cistatic inline void ef4_filter_rfs_expire(struct ef4_channel *channel) 16862306a36Sopenharmony_ci{ 16962306a36Sopenharmony_ci if (channel->rfs_filters_added >= 60 && 17062306a36Sopenharmony_ci __ef4_filter_rfs_expire(channel->efx, 100)) 17162306a36Sopenharmony_ci channel->rfs_filters_added -= 60; 17262306a36Sopenharmony_ci} 17362306a36Sopenharmony_ci#define ef4_filter_rfs_enabled() 1 17462306a36Sopenharmony_ci#else 17562306a36Sopenharmony_cistatic inline void ef4_filter_rfs_expire(struct ef4_channel *channel) {} 17662306a36Sopenharmony_ci#define ef4_filter_rfs_enabled() 0 17762306a36Sopenharmony_ci#endif 17862306a36Sopenharmony_cibool ef4_filter_is_mc_recipient(const struct ef4_filter_spec *spec); 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci/* Channels */ 18162306a36Sopenharmony_ciint ef4_channel_dummy_op_int(struct ef4_channel *channel); 18262306a36Sopenharmony_civoid ef4_channel_dummy_op_void(struct ef4_channel *channel); 18362306a36Sopenharmony_ciint ef4_realloc_channels(struct ef4_nic *efx, u32 rxq_entries, u32 txq_entries); 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci/* Ports */ 18662306a36Sopenharmony_ciint ef4_reconfigure_port(struct ef4_nic *efx); 18762306a36Sopenharmony_ciint __ef4_reconfigure_port(struct ef4_nic *efx); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci/* Ethtool support */ 19062306a36Sopenharmony_ciextern const struct ethtool_ops ef4_ethtool_ops; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci/* Reset handling */ 19362306a36Sopenharmony_ciint ef4_reset(struct ef4_nic *efx, enum reset_type method); 19462306a36Sopenharmony_civoid ef4_reset_down(struct ef4_nic *efx, enum reset_type method); 19562306a36Sopenharmony_ciint ef4_reset_up(struct ef4_nic *efx, enum reset_type method, bool ok); 19662306a36Sopenharmony_ciint ef4_try_recovery(struct ef4_nic *efx); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci/* Global */ 19962306a36Sopenharmony_civoid ef4_schedule_reset(struct ef4_nic *efx, enum reset_type type); 20062306a36Sopenharmony_ciunsigned int ef4_usecs_to_ticks(struct ef4_nic *efx, unsigned int usecs); 20162306a36Sopenharmony_ciunsigned int ef4_ticks_to_usecs(struct ef4_nic *efx, unsigned int ticks); 20262306a36Sopenharmony_ciint ef4_init_irq_moderation(struct ef4_nic *efx, unsigned int tx_usecs, 20362306a36Sopenharmony_ci unsigned int rx_usecs, bool rx_adaptive, 20462306a36Sopenharmony_ci bool rx_may_override_tx); 20562306a36Sopenharmony_civoid ef4_get_irq_moderation(struct ef4_nic *efx, unsigned int *tx_usecs, 20662306a36Sopenharmony_ci unsigned int *rx_usecs, bool *rx_adaptive); 20762306a36Sopenharmony_civoid ef4_stop_eventq(struct ef4_channel *channel); 20862306a36Sopenharmony_civoid ef4_start_eventq(struct ef4_channel *channel); 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci/* Dummy PHY ops for PHY drivers */ 21162306a36Sopenharmony_ciint ef4_port_dummy_op_int(struct ef4_nic *efx); 21262306a36Sopenharmony_civoid ef4_port_dummy_op_void(struct ef4_nic *efx); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci/* Update the generic software stats in the passed stats array */ 21562306a36Sopenharmony_civoid ef4_update_sw_stats(struct ef4_nic *efx, u64 *stats); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci/* MTD */ 21862306a36Sopenharmony_ci#ifdef CONFIG_SFC_FALCON_MTD 21962306a36Sopenharmony_ciint ef4_mtd_add(struct ef4_nic *efx, struct ef4_mtd_partition *parts, 22062306a36Sopenharmony_ci size_t n_parts, size_t sizeof_part); 22162306a36Sopenharmony_cistatic inline int ef4_mtd_probe(struct ef4_nic *efx) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci return efx->type->mtd_probe(efx); 22462306a36Sopenharmony_ci} 22562306a36Sopenharmony_civoid ef4_mtd_rename(struct ef4_nic *efx); 22662306a36Sopenharmony_civoid ef4_mtd_remove(struct ef4_nic *efx); 22762306a36Sopenharmony_ci#else 22862306a36Sopenharmony_cistatic inline int ef4_mtd_probe(struct ef4_nic *efx) { return 0; } 22962306a36Sopenharmony_cistatic inline void ef4_mtd_rename(struct ef4_nic *efx) {} 23062306a36Sopenharmony_cistatic inline void ef4_mtd_remove(struct ef4_nic *efx) {} 23162306a36Sopenharmony_ci#endif 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_cistatic inline void ef4_schedule_channel(struct ef4_channel *channel) 23462306a36Sopenharmony_ci{ 23562306a36Sopenharmony_ci netif_vdbg(channel->efx, intr, channel->efx->net_dev, 23662306a36Sopenharmony_ci "channel %d scheduling NAPI poll on CPU%d\n", 23762306a36Sopenharmony_ci channel->channel, raw_smp_processor_id()); 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci napi_schedule(&channel->napi_str); 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cistatic inline void ef4_schedule_channel_irq(struct ef4_channel *channel) 24362306a36Sopenharmony_ci{ 24462306a36Sopenharmony_ci channel->event_test_cpu = raw_smp_processor_id(); 24562306a36Sopenharmony_ci ef4_schedule_channel(channel); 24662306a36Sopenharmony_ci} 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_civoid ef4_link_status_changed(struct ef4_nic *efx); 24962306a36Sopenharmony_civoid ef4_link_set_advertising(struct ef4_nic *efx, u32); 25062306a36Sopenharmony_civoid ef4_link_set_wanted_fc(struct ef4_nic *efx, u8); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_cistatic inline void ef4_device_detach_sync(struct ef4_nic *efx) 25362306a36Sopenharmony_ci{ 25462306a36Sopenharmony_ci struct net_device *dev = efx->net_dev; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci /* Lock/freeze all TX queues so that we can be sure the 25762306a36Sopenharmony_ci * TX scheduler is stopped when we're done and before 25862306a36Sopenharmony_ci * netif_device_present() becomes false. 25962306a36Sopenharmony_ci */ 26062306a36Sopenharmony_ci netif_tx_lock_bh(dev); 26162306a36Sopenharmony_ci netif_device_detach(dev); 26262306a36Sopenharmony_ci netif_tx_unlock_bh(dev); 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_cistatic inline bool ef4_rwsem_assert_write_locked(struct rw_semaphore *sem) 26662306a36Sopenharmony_ci{ 26762306a36Sopenharmony_ci if (WARN_ON(down_read_trylock(sem))) { 26862306a36Sopenharmony_ci up_read(sem); 26962306a36Sopenharmony_ci return false; 27062306a36Sopenharmony_ci } 27162306a36Sopenharmony_ci return true; 27262306a36Sopenharmony_ci} 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci#endif /* EF4_EFX_H */ 275