18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/**************************************************************************** 38c2ecf20Sopenharmony_ci * Driver for Solarflare network controllers and boards 48c2ecf20Sopenharmony_ci * Copyright 2005-2006 Fen Systems Ltd. 58c2ecf20Sopenharmony_ci * Copyright 2006-2013 Solarflare Communications Inc. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifndef EF4_EFX_H 98c2ecf20Sopenharmony_ci#define EF4_EFX_H 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include "net_driver.h" 128c2ecf20Sopenharmony_ci#include "filter.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* All controllers use BAR 0 for I/O space and BAR 2(&3) for memory */ 158c2ecf20Sopenharmony_ci/* All VFs use BAR 0/1 for memory */ 168c2ecf20Sopenharmony_ci#define EF4_MEM_BAR 2 178c2ecf20Sopenharmony_ci#define EF4_MEM_VF_BAR 0 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ciint ef4_net_open(struct net_device *net_dev); 208c2ecf20Sopenharmony_ciint ef4_net_stop(struct net_device *net_dev); 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* TX */ 238c2ecf20Sopenharmony_ciint ef4_probe_tx_queue(struct ef4_tx_queue *tx_queue); 248c2ecf20Sopenharmony_civoid ef4_remove_tx_queue(struct ef4_tx_queue *tx_queue); 258c2ecf20Sopenharmony_civoid ef4_init_tx_queue(struct ef4_tx_queue *tx_queue); 268c2ecf20Sopenharmony_civoid ef4_init_tx_queue_core_txq(struct ef4_tx_queue *tx_queue); 278c2ecf20Sopenharmony_civoid ef4_fini_tx_queue(struct ef4_tx_queue *tx_queue); 288c2ecf20Sopenharmony_cinetdev_tx_t ef4_hard_start_xmit(struct sk_buff *skb, 298c2ecf20Sopenharmony_ci struct net_device *net_dev); 308c2ecf20Sopenharmony_cinetdev_tx_t ef4_enqueue_skb(struct ef4_tx_queue *tx_queue, struct sk_buff *skb); 318c2ecf20Sopenharmony_civoid ef4_xmit_done(struct ef4_tx_queue *tx_queue, unsigned int index); 328c2ecf20Sopenharmony_ciint ef4_setup_tc(struct net_device *net_dev, enum tc_setup_type type, 338c2ecf20Sopenharmony_ci void *type_data); 348c2ecf20Sopenharmony_ciunsigned int ef4_tx_max_skb_descs(struct ef4_nic *efx); 358c2ecf20Sopenharmony_ciextern bool ef4_separate_tx_channels; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* RX */ 388c2ecf20Sopenharmony_civoid ef4_set_default_rx_indir_table(struct ef4_nic *efx); 398c2ecf20Sopenharmony_civoid ef4_rx_config_page_split(struct ef4_nic *efx); 408c2ecf20Sopenharmony_ciint ef4_probe_rx_queue(struct ef4_rx_queue *rx_queue); 418c2ecf20Sopenharmony_civoid ef4_remove_rx_queue(struct ef4_rx_queue *rx_queue); 428c2ecf20Sopenharmony_civoid ef4_init_rx_queue(struct ef4_rx_queue *rx_queue); 438c2ecf20Sopenharmony_civoid ef4_fini_rx_queue(struct ef4_rx_queue *rx_queue); 448c2ecf20Sopenharmony_civoid ef4_fast_push_rx_descriptors(struct ef4_rx_queue *rx_queue, bool atomic); 458c2ecf20Sopenharmony_civoid ef4_rx_slow_fill(struct timer_list *t); 468c2ecf20Sopenharmony_civoid __ef4_rx_packet(struct ef4_channel *channel); 478c2ecf20Sopenharmony_civoid ef4_rx_packet(struct ef4_rx_queue *rx_queue, unsigned int index, 488c2ecf20Sopenharmony_ci unsigned int n_frags, unsigned int len, u16 flags); 498c2ecf20Sopenharmony_cistatic inline void ef4_rx_flush_packet(struct ef4_channel *channel) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci if (channel->rx_pkt_n_frags) 528c2ecf20Sopenharmony_ci __ef4_rx_packet(channel); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_civoid ef4_schedule_slow_fill(struct ef4_rx_queue *rx_queue); 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#define EF4_MAX_DMAQ_SIZE 4096UL 578c2ecf20Sopenharmony_ci#define EF4_DEFAULT_DMAQ_SIZE 1024UL 588c2ecf20Sopenharmony_ci#define EF4_MIN_DMAQ_SIZE 512UL 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#define EF4_MAX_EVQ_SIZE 16384UL 618c2ecf20Sopenharmony_ci#define EF4_MIN_EVQ_SIZE 512UL 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci/* Maximum number of TCP segments we support for soft-TSO */ 648c2ecf20Sopenharmony_ci#define EF4_TSO_MAX_SEGS 100 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci/* The smallest [rt]xq_entries that the driver supports. RX minimum 678c2ecf20Sopenharmony_ci * is a bit arbitrary. For TX, we must have space for at least 2 688c2ecf20Sopenharmony_ci * TSO skbs. 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_ci#define EF4_RXQ_MIN_ENT 128U 718c2ecf20Sopenharmony_ci#define EF4_TXQ_MIN_ENT(efx) (2 * ef4_tx_max_skb_descs(efx)) 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistatic inline bool ef4_rss_enabled(struct ef4_nic *efx) 748c2ecf20Sopenharmony_ci{ 758c2ecf20Sopenharmony_ci return efx->rss_spread > 1; 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci/* Filters */ 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_civoid ef4_mac_reconfigure(struct ef4_nic *efx); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci/** 838c2ecf20Sopenharmony_ci * ef4_filter_insert_filter - add or replace a filter 848c2ecf20Sopenharmony_ci * @efx: NIC in which to insert the filter 858c2ecf20Sopenharmony_ci * @spec: Specification for the filter 868c2ecf20Sopenharmony_ci * @replace_equal: Flag for whether the specified filter may replace an 878c2ecf20Sopenharmony_ci * existing filter with equal priority 888c2ecf20Sopenharmony_ci * 898c2ecf20Sopenharmony_ci * On success, return the filter ID. 908c2ecf20Sopenharmony_ci * On failure, return a negative error code. 918c2ecf20Sopenharmony_ci * 928c2ecf20Sopenharmony_ci * If existing filters have equal match values to the new filter spec, 938c2ecf20Sopenharmony_ci * then the new filter might replace them or the function might fail, 948c2ecf20Sopenharmony_ci * as follows. 958c2ecf20Sopenharmony_ci * 968c2ecf20Sopenharmony_ci * 1. If the existing filters have lower priority, or @replace_equal 978c2ecf20Sopenharmony_ci * is set and they have equal priority, replace them. 988c2ecf20Sopenharmony_ci * 998c2ecf20Sopenharmony_ci * 2. If the existing filters have higher priority, return -%EPERM. 1008c2ecf20Sopenharmony_ci * 1018c2ecf20Sopenharmony_ci * 3. If !ef4_filter_is_mc_recipient(@spec), or the NIC does not 1028c2ecf20Sopenharmony_ci * support delivery to multiple recipients, return -%EEXIST. 1038c2ecf20Sopenharmony_ci * 1048c2ecf20Sopenharmony_ci * This implies that filters for multiple multicast recipients must 1058c2ecf20Sopenharmony_ci * all be inserted with the same priority and @replace_equal = %false. 1068c2ecf20Sopenharmony_ci */ 1078c2ecf20Sopenharmony_cistatic inline s32 ef4_filter_insert_filter(struct ef4_nic *efx, 1088c2ecf20Sopenharmony_ci struct ef4_filter_spec *spec, 1098c2ecf20Sopenharmony_ci bool replace_equal) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci return efx->type->filter_insert(efx, spec, replace_equal); 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci/** 1158c2ecf20Sopenharmony_ci * ef4_filter_remove_id_safe - remove a filter by ID, carefully 1168c2ecf20Sopenharmony_ci * @efx: NIC from which to remove the filter 1178c2ecf20Sopenharmony_ci * @priority: Priority of filter, as passed to @ef4_filter_insert_filter 1188c2ecf20Sopenharmony_ci * @filter_id: ID of filter, as returned by @ef4_filter_insert_filter 1198c2ecf20Sopenharmony_ci * 1208c2ecf20Sopenharmony_ci * This function will range-check @filter_id, so it is safe to call 1218c2ecf20Sopenharmony_ci * with a value passed from userland. 1228c2ecf20Sopenharmony_ci */ 1238c2ecf20Sopenharmony_cistatic inline int ef4_filter_remove_id_safe(struct ef4_nic *efx, 1248c2ecf20Sopenharmony_ci enum ef4_filter_priority priority, 1258c2ecf20Sopenharmony_ci u32 filter_id) 1268c2ecf20Sopenharmony_ci{ 1278c2ecf20Sopenharmony_ci return efx->type->filter_remove_safe(efx, priority, filter_id); 1288c2ecf20Sopenharmony_ci} 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci/** 1318c2ecf20Sopenharmony_ci * ef4_filter_get_filter_safe - retrieve a filter by ID, carefully 1328c2ecf20Sopenharmony_ci * @efx: NIC from which to remove the filter 1338c2ecf20Sopenharmony_ci * @priority: Priority of filter, as passed to @ef4_filter_insert_filter 1348c2ecf20Sopenharmony_ci * @filter_id: ID of filter, as returned by @ef4_filter_insert_filter 1358c2ecf20Sopenharmony_ci * @spec: Buffer in which to store filter specification 1368c2ecf20Sopenharmony_ci * 1378c2ecf20Sopenharmony_ci * This function will range-check @filter_id, so it is safe to call 1388c2ecf20Sopenharmony_ci * with a value passed from userland. 1398c2ecf20Sopenharmony_ci */ 1408c2ecf20Sopenharmony_cistatic inline int 1418c2ecf20Sopenharmony_cief4_filter_get_filter_safe(struct ef4_nic *efx, 1428c2ecf20Sopenharmony_ci enum ef4_filter_priority priority, 1438c2ecf20Sopenharmony_ci u32 filter_id, struct ef4_filter_spec *spec) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci return efx->type->filter_get_safe(efx, priority, filter_id, spec); 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic inline u32 ef4_filter_count_rx_used(struct ef4_nic *efx, 1498c2ecf20Sopenharmony_ci enum ef4_filter_priority priority) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci return efx->type->filter_count_rx_used(efx, priority); 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_cistatic inline u32 ef4_filter_get_rx_id_limit(struct ef4_nic *efx) 1548c2ecf20Sopenharmony_ci{ 1558c2ecf20Sopenharmony_ci return efx->type->filter_get_rx_id_limit(efx); 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_cistatic inline s32 ef4_filter_get_rx_ids(struct ef4_nic *efx, 1588c2ecf20Sopenharmony_ci enum ef4_filter_priority priority, 1598c2ecf20Sopenharmony_ci u32 *buf, u32 size) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci return efx->type->filter_get_rx_ids(efx, priority, buf, size); 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci#ifdef CONFIG_RFS_ACCEL 1648c2ecf20Sopenharmony_ciint ef4_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, 1658c2ecf20Sopenharmony_ci u16 rxq_index, u32 flow_id); 1668c2ecf20Sopenharmony_cibool __ef4_filter_rfs_expire(struct ef4_nic *efx, unsigned quota); 1678c2ecf20Sopenharmony_cistatic inline void ef4_filter_rfs_expire(struct ef4_channel *channel) 1688c2ecf20Sopenharmony_ci{ 1698c2ecf20Sopenharmony_ci if (channel->rfs_filters_added >= 60 && 1708c2ecf20Sopenharmony_ci __ef4_filter_rfs_expire(channel->efx, 100)) 1718c2ecf20Sopenharmony_ci channel->rfs_filters_added -= 60; 1728c2ecf20Sopenharmony_ci} 1738c2ecf20Sopenharmony_ci#define ef4_filter_rfs_enabled() 1 1748c2ecf20Sopenharmony_ci#else 1758c2ecf20Sopenharmony_cistatic inline void ef4_filter_rfs_expire(struct ef4_channel *channel) {} 1768c2ecf20Sopenharmony_ci#define ef4_filter_rfs_enabled() 0 1778c2ecf20Sopenharmony_ci#endif 1788c2ecf20Sopenharmony_cibool ef4_filter_is_mc_recipient(const struct ef4_filter_spec *spec); 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci/* Channels */ 1818c2ecf20Sopenharmony_ciint ef4_channel_dummy_op_int(struct ef4_channel *channel); 1828c2ecf20Sopenharmony_civoid ef4_channel_dummy_op_void(struct ef4_channel *channel); 1838c2ecf20Sopenharmony_ciint ef4_realloc_channels(struct ef4_nic *efx, u32 rxq_entries, u32 txq_entries); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci/* Ports */ 1868c2ecf20Sopenharmony_ciint ef4_reconfigure_port(struct ef4_nic *efx); 1878c2ecf20Sopenharmony_ciint __ef4_reconfigure_port(struct ef4_nic *efx); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci/* Ethtool support */ 1908c2ecf20Sopenharmony_ciextern const struct ethtool_ops ef4_ethtool_ops; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci/* Reset handling */ 1938c2ecf20Sopenharmony_ciint ef4_reset(struct ef4_nic *efx, enum reset_type method); 1948c2ecf20Sopenharmony_civoid ef4_reset_down(struct ef4_nic *efx, enum reset_type method); 1958c2ecf20Sopenharmony_ciint ef4_reset_up(struct ef4_nic *efx, enum reset_type method, bool ok); 1968c2ecf20Sopenharmony_ciint ef4_try_recovery(struct ef4_nic *efx); 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci/* Global */ 1998c2ecf20Sopenharmony_civoid ef4_schedule_reset(struct ef4_nic *efx, enum reset_type type); 2008c2ecf20Sopenharmony_ciunsigned int ef4_usecs_to_ticks(struct ef4_nic *efx, unsigned int usecs); 2018c2ecf20Sopenharmony_ciunsigned int ef4_ticks_to_usecs(struct ef4_nic *efx, unsigned int ticks); 2028c2ecf20Sopenharmony_ciint ef4_init_irq_moderation(struct ef4_nic *efx, unsigned int tx_usecs, 2038c2ecf20Sopenharmony_ci unsigned int rx_usecs, bool rx_adaptive, 2048c2ecf20Sopenharmony_ci bool rx_may_override_tx); 2058c2ecf20Sopenharmony_civoid ef4_get_irq_moderation(struct ef4_nic *efx, unsigned int *tx_usecs, 2068c2ecf20Sopenharmony_ci unsigned int *rx_usecs, bool *rx_adaptive); 2078c2ecf20Sopenharmony_civoid ef4_stop_eventq(struct ef4_channel *channel); 2088c2ecf20Sopenharmony_civoid ef4_start_eventq(struct ef4_channel *channel); 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci/* Dummy PHY ops for PHY drivers */ 2118c2ecf20Sopenharmony_ciint ef4_port_dummy_op_int(struct ef4_nic *efx); 2128c2ecf20Sopenharmony_civoid ef4_port_dummy_op_void(struct ef4_nic *efx); 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci/* Update the generic software stats in the passed stats array */ 2158c2ecf20Sopenharmony_civoid ef4_update_sw_stats(struct ef4_nic *efx, u64 *stats); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci/* MTD */ 2188c2ecf20Sopenharmony_ci#ifdef CONFIG_SFC_FALCON_MTD 2198c2ecf20Sopenharmony_ciint ef4_mtd_add(struct ef4_nic *efx, struct ef4_mtd_partition *parts, 2208c2ecf20Sopenharmony_ci size_t n_parts, size_t sizeof_part); 2218c2ecf20Sopenharmony_cistatic inline int ef4_mtd_probe(struct ef4_nic *efx) 2228c2ecf20Sopenharmony_ci{ 2238c2ecf20Sopenharmony_ci return efx->type->mtd_probe(efx); 2248c2ecf20Sopenharmony_ci} 2258c2ecf20Sopenharmony_civoid ef4_mtd_rename(struct ef4_nic *efx); 2268c2ecf20Sopenharmony_civoid ef4_mtd_remove(struct ef4_nic *efx); 2278c2ecf20Sopenharmony_ci#else 2288c2ecf20Sopenharmony_cistatic inline int ef4_mtd_probe(struct ef4_nic *efx) { return 0; } 2298c2ecf20Sopenharmony_cistatic inline void ef4_mtd_rename(struct ef4_nic *efx) {} 2308c2ecf20Sopenharmony_cistatic inline void ef4_mtd_remove(struct ef4_nic *efx) {} 2318c2ecf20Sopenharmony_ci#endif 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_cistatic inline void ef4_schedule_channel(struct ef4_channel *channel) 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci netif_vdbg(channel->efx, intr, channel->efx->net_dev, 2368c2ecf20Sopenharmony_ci "channel %d scheduling NAPI poll on CPU%d\n", 2378c2ecf20Sopenharmony_ci channel->channel, raw_smp_processor_id()); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci napi_schedule(&channel->napi_str); 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistatic inline void ef4_schedule_channel_irq(struct ef4_channel *channel) 2438c2ecf20Sopenharmony_ci{ 2448c2ecf20Sopenharmony_ci channel->event_test_cpu = raw_smp_processor_id(); 2458c2ecf20Sopenharmony_ci ef4_schedule_channel(channel); 2468c2ecf20Sopenharmony_ci} 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_civoid ef4_link_status_changed(struct ef4_nic *efx); 2498c2ecf20Sopenharmony_civoid ef4_link_set_advertising(struct ef4_nic *efx, u32); 2508c2ecf20Sopenharmony_civoid ef4_link_set_wanted_fc(struct ef4_nic *efx, u8); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic inline void ef4_device_detach_sync(struct ef4_nic *efx) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci struct net_device *dev = efx->net_dev; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci /* Lock/freeze all TX queues so that we can be sure the 2578c2ecf20Sopenharmony_ci * TX scheduler is stopped when we're done and before 2588c2ecf20Sopenharmony_ci * netif_device_present() becomes false. 2598c2ecf20Sopenharmony_ci */ 2608c2ecf20Sopenharmony_ci netif_tx_lock_bh(dev); 2618c2ecf20Sopenharmony_ci netif_device_detach(dev); 2628c2ecf20Sopenharmony_ci netif_tx_unlock_bh(dev); 2638c2ecf20Sopenharmony_ci} 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_cistatic inline bool ef4_rwsem_assert_write_locked(struct rw_semaphore *sem) 2668c2ecf20Sopenharmony_ci{ 2678c2ecf20Sopenharmony_ci if (WARN_ON(down_read_trylock(sem))) { 2688c2ecf20Sopenharmony_ci up_read(sem); 2698c2ecf20Sopenharmony_ci return false; 2708c2ecf20Sopenharmony_ci } 2718c2ecf20Sopenharmony_ci return true; 2728c2ecf20Sopenharmony_ci} 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci#endif /* EF4_EFX_H */ 275