162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. 462306a36Sopenharmony_ci * Copyright 2007 Nuova Systems, Inc. All rights reserved. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef _ENIC_H_ 862306a36Sopenharmony_ci#define _ENIC_H_ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "vnic_enet.h" 1162306a36Sopenharmony_ci#include "vnic_dev.h" 1262306a36Sopenharmony_ci#include "vnic_wq.h" 1362306a36Sopenharmony_ci#include "vnic_rq.h" 1462306a36Sopenharmony_ci#include "vnic_cq.h" 1562306a36Sopenharmony_ci#include "vnic_intr.h" 1662306a36Sopenharmony_ci#include "vnic_stats.h" 1762306a36Sopenharmony_ci#include "vnic_nic.h" 1862306a36Sopenharmony_ci#include "vnic_rss.h" 1962306a36Sopenharmony_ci#include <linux/irq.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define DRV_NAME "enic" 2262306a36Sopenharmony_ci#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define ENIC_BARS_MAX 6 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#define ENIC_WQ_MAX 8 2762306a36Sopenharmony_ci#define ENIC_RQ_MAX 8 2862306a36Sopenharmony_ci#define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) 2962306a36Sopenharmony_ci#define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define ENIC_WQ_NAPI_BUDGET 256 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define ENIC_AIC_LARGE_PKT_DIFF 3 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistruct enic_msix_entry { 3662306a36Sopenharmony_ci int requested; 3762306a36Sopenharmony_ci char devname[IFNAMSIZ + 8]; 3862306a36Sopenharmony_ci irqreturn_t (*isr)(int, void *); 3962306a36Sopenharmony_ci void *devid; 4062306a36Sopenharmony_ci cpumask_var_t affinity_mask; 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* Store only the lower range. Higher range is given by fw. */ 4462306a36Sopenharmony_cistruct enic_intr_mod_range { 4562306a36Sopenharmony_ci u32 small_pkt_range_start; 4662306a36Sopenharmony_ci u32 large_pkt_range_start; 4762306a36Sopenharmony_ci}; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistruct enic_intr_mod_table { 5062306a36Sopenharmony_ci u32 rx_rate; 5162306a36Sopenharmony_ci u32 range_percent; 5262306a36Sopenharmony_ci}; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#define ENIC_MAX_LINK_SPEEDS 3 5562306a36Sopenharmony_ci#define ENIC_LINK_SPEED_10G 10000 5662306a36Sopenharmony_ci#define ENIC_LINK_SPEED_4G 4000 5762306a36Sopenharmony_ci#define ENIC_LINK_40G_INDEX 2 5862306a36Sopenharmony_ci#define ENIC_LINK_10G_INDEX 1 5962306a36Sopenharmony_ci#define ENIC_LINK_4G_INDEX 0 6062306a36Sopenharmony_ci#define ENIC_RX_COALESCE_RANGE_END 125 6162306a36Sopenharmony_ci#define ENIC_AIC_TS_BREAK 100 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistruct enic_rx_coal { 6462306a36Sopenharmony_ci u32 small_pkt_range_start; 6562306a36Sopenharmony_ci u32 large_pkt_range_start; 6662306a36Sopenharmony_ci u32 range_end; 6762306a36Sopenharmony_ci u32 use_adaptive_rx_coalesce; 6862306a36Sopenharmony_ci}; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* priv_flags */ 7162306a36Sopenharmony_ci#define ENIC_SRIOV_ENABLED (1 << 0) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/* enic port profile set flags */ 7462306a36Sopenharmony_ci#define ENIC_PORT_REQUEST_APPLIED (1 << 0) 7562306a36Sopenharmony_ci#define ENIC_SET_REQUEST (1 << 1) 7662306a36Sopenharmony_ci#define ENIC_SET_NAME (1 << 2) 7762306a36Sopenharmony_ci#define ENIC_SET_INSTANCE (1 << 3) 7862306a36Sopenharmony_ci#define ENIC_SET_HOST (1 << 4) 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cistruct enic_port_profile { 8162306a36Sopenharmony_ci u32 set; 8262306a36Sopenharmony_ci u8 request; 8362306a36Sopenharmony_ci char name[PORT_PROFILE_MAX]; 8462306a36Sopenharmony_ci u8 instance_uuid[PORT_UUID_MAX]; 8562306a36Sopenharmony_ci u8 host_uuid[PORT_UUID_MAX]; 8662306a36Sopenharmony_ci u8 vf_mac[ETH_ALEN]; 8762306a36Sopenharmony_ci u8 mac_addr[ETH_ALEN]; 8862306a36Sopenharmony_ci}; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/* enic_rfs_fltr_node - rfs filter node in hash table 9162306a36Sopenharmony_ci * @@keys: IPv4 5 tuple 9262306a36Sopenharmony_ci * @flow_id: flow_id of clsf filter provided by kernel 9362306a36Sopenharmony_ci * @fltr_id: filter id of clsf filter returned by adaptor 9462306a36Sopenharmony_ci * @rq_id: desired rq index 9562306a36Sopenharmony_ci * @node: hlist_node 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_cistruct enic_rfs_fltr_node { 9862306a36Sopenharmony_ci struct flow_keys keys; 9962306a36Sopenharmony_ci u32 flow_id; 10062306a36Sopenharmony_ci u16 fltr_id; 10162306a36Sopenharmony_ci u16 rq_id; 10262306a36Sopenharmony_ci struct hlist_node node; 10362306a36Sopenharmony_ci}; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* enic_rfs_flw_tbl - rfs flow table 10662306a36Sopenharmony_ci * @max: Maximum number of filters vNIC supports 10762306a36Sopenharmony_ci * @free: Number of free filters available 10862306a36Sopenharmony_ci * @toclean: hash table index to clean next 10962306a36Sopenharmony_ci * @ht_head: hash table list head 11062306a36Sopenharmony_ci * @lock: spin lock 11162306a36Sopenharmony_ci * @rfs_may_expire: timer function for enic_rps_may_expire_flow 11262306a36Sopenharmony_ci */ 11362306a36Sopenharmony_cistruct enic_rfs_flw_tbl { 11462306a36Sopenharmony_ci u16 max; 11562306a36Sopenharmony_ci int free; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci#define ENIC_RFS_FLW_BITSHIFT (10) 11862306a36Sopenharmony_ci#define ENIC_RFS_FLW_MASK ((1 << ENIC_RFS_FLW_BITSHIFT) - 1) 11962306a36Sopenharmony_ci u16 toclean:ENIC_RFS_FLW_BITSHIFT; 12062306a36Sopenharmony_ci struct hlist_head ht_head[1 << ENIC_RFS_FLW_BITSHIFT]; 12162306a36Sopenharmony_ci spinlock_t lock; 12262306a36Sopenharmony_ci struct timer_list rfs_may_expire; 12362306a36Sopenharmony_ci}; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistruct vxlan_offload { 12662306a36Sopenharmony_ci u16 vxlan_udp_port_number; 12762306a36Sopenharmony_ci u8 patch_level; 12862306a36Sopenharmony_ci u8 flags; 12962306a36Sopenharmony_ci}; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci/* Per-instance private data structure */ 13262306a36Sopenharmony_cistruct enic { 13362306a36Sopenharmony_ci struct net_device *netdev; 13462306a36Sopenharmony_ci struct pci_dev *pdev; 13562306a36Sopenharmony_ci struct vnic_enet_config config; 13662306a36Sopenharmony_ci struct vnic_dev_bar bar[ENIC_BARS_MAX]; 13762306a36Sopenharmony_ci struct vnic_dev *vdev; 13862306a36Sopenharmony_ci struct timer_list notify_timer; 13962306a36Sopenharmony_ci struct work_struct reset; 14062306a36Sopenharmony_ci struct work_struct tx_hang_reset; 14162306a36Sopenharmony_ci struct work_struct change_mtu_work; 14262306a36Sopenharmony_ci struct msix_entry msix_entry[ENIC_INTR_MAX]; 14362306a36Sopenharmony_ci struct enic_msix_entry msix[ENIC_INTR_MAX]; 14462306a36Sopenharmony_ci u32 msg_enable; 14562306a36Sopenharmony_ci spinlock_t devcmd_lock; 14662306a36Sopenharmony_ci u8 mac_addr[ETH_ALEN]; 14762306a36Sopenharmony_ci unsigned int flags; 14862306a36Sopenharmony_ci unsigned int priv_flags; 14962306a36Sopenharmony_ci unsigned int mc_count; 15062306a36Sopenharmony_ci unsigned int uc_count; 15162306a36Sopenharmony_ci u32 port_mtu; 15262306a36Sopenharmony_ci struct enic_rx_coal rx_coalesce_setting; 15362306a36Sopenharmony_ci u32 rx_coalesce_usecs; 15462306a36Sopenharmony_ci u32 tx_coalesce_usecs; 15562306a36Sopenharmony_ci#ifdef CONFIG_PCI_IOV 15662306a36Sopenharmony_ci u16 num_vfs; 15762306a36Sopenharmony_ci#endif 15862306a36Sopenharmony_ci spinlock_t enic_api_lock; 15962306a36Sopenharmony_ci bool enic_api_busy; 16062306a36Sopenharmony_ci struct enic_port_profile *pp; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci /* work queue cache line section */ 16362306a36Sopenharmony_ci ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX]; 16462306a36Sopenharmony_ci spinlock_t wq_lock[ENIC_WQ_MAX]; 16562306a36Sopenharmony_ci unsigned int wq_count; 16662306a36Sopenharmony_ci u16 loop_enable; 16762306a36Sopenharmony_ci u16 loop_tag; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci /* receive queue cache line section */ 17062306a36Sopenharmony_ci ____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX]; 17162306a36Sopenharmony_ci unsigned int rq_count; 17262306a36Sopenharmony_ci struct vxlan_offload vxlan; 17362306a36Sopenharmony_ci u64 rq_truncated_pkts; 17462306a36Sopenharmony_ci u64 rq_bad_fcs; 17562306a36Sopenharmony_ci struct napi_struct napi[ENIC_RQ_MAX + ENIC_WQ_MAX]; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci /* interrupt resource cache line section */ 17862306a36Sopenharmony_ci ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; 17962306a36Sopenharmony_ci unsigned int intr_count; 18062306a36Sopenharmony_ci u32 __iomem *legacy_pba; /* memory-mapped */ 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci /* completion queue cache line section */ 18362306a36Sopenharmony_ci ____cacheline_aligned struct vnic_cq cq[ENIC_CQ_MAX]; 18462306a36Sopenharmony_ci unsigned int cq_count; 18562306a36Sopenharmony_ci struct enic_rfs_flw_tbl rfs_h; 18662306a36Sopenharmony_ci u32 rx_copybreak; 18762306a36Sopenharmony_ci u8 rss_key[ENIC_RSS_LEN]; 18862306a36Sopenharmony_ci struct vnic_gen_stats gen_stats; 18962306a36Sopenharmony_ci}; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cistatic inline struct net_device *vnic_get_netdev(struct vnic_dev *vdev) 19262306a36Sopenharmony_ci{ 19362306a36Sopenharmony_ci struct enic *enic = vdev->priv; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci return enic->netdev; 19662306a36Sopenharmony_ci} 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci/* wrappers function for kernel log 19962306a36Sopenharmony_ci */ 20062306a36Sopenharmony_ci#define vdev_err(vdev, fmt, ...) \ 20162306a36Sopenharmony_ci dev_err(&(vdev)->pdev->dev, fmt, ##__VA_ARGS__) 20262306a36Sopenharmony_ci#define vdev_warn(vdev, fmt, ...) \ 20362306a36Sopenharmony_ci dev_warn(&(vdev)->pdev->dev, fmt, ##__VA_ARGS__) 20462306a36Sopenharmony_ci#define vdev_info(vdev, fmt, ...) \ 20562306a36Sopenharmony_ci dev_info(&(vdev)->pdev->dev, fmt, ##__VA_ARGS__) 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci#define vdev_neterr(vdev, fmt, ...) \ 20862306a36Sopenharmony_ci netdev_err(vnic_get_netdev(vdev), fmt, ##__VA_ARGS__) 20962306a36Sopenharmony_ci#define vdev_netwarn(vdev, fmt, ...) \ 21062306a36Sopenharmony_ci netdev_warn(vnic_get_netdev(vdev), fmt, ##__VA_ARGS__) 21162306a36Sopenharmony_ci#define vdev_netinfo(vdev, fmt, ...) \ 21262306a36Sopenharmony_ci netdev_info(vnic_get_netdev(vdev), fmt, ##__VA_ARGS__) 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_cistatic inline struct device *enic_get_dev(struct enic *enic) 21562306a36Sopenharmony_ci{ 21662306a36Sopenharmony_ci return &(enic->pdev->dev); 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistatic inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci return rq; 22262306a36Sopenharmony_ci} 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cistatic inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq) 22562306a36Sopenharmony_ci{ 22662306a36Sopenharmony_ci return enic->rq_count + wq; 22762306a36Sopenharmony_ci} 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_cistatic inline unsigned int enic_msix_rq_intr(struct enic *enic, 23062306a36Sopenharmony_ci unsigned int rq) 23162306a36Sopenharmony_ci{ 23262306a36Sopenharmony_ci return enic->cq[enic_cq_rq(enic, rq)].interrupt_offset; 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic inline unsigned int enic_msix_wq_intr(struct enic *enic, 23662306a36Sopenharmony_ci unsigned int wq) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci return enic->cq[enic_cq_wq(enic, wq)].interrupt_offset; 23962306a36Sopenharmony_ci} 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_cistatic inline unsigned int enic_msix_err_intr(struct enic *enic) 24262306a36Sopenharmony_ci{ 24362306a36Sopenharmony_ci return enic->rq_count + enic->wq_count; 24462306a36Sopenharmony_ci} 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci#define ENIC_LEGACY_IO_INTR 0 24762306a36Sopenharmony_ci#define ENIC_LEGACY_ERR_INTR 1 24862306a36Sopenharmony_ci#define ENIC_LEGACY_NOTIFY_INTR 2 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic inline unsigned int enic_msix_notify_intr(struct enic *enic) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci return enic->rq_count + enic->wq_count + 1; 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_cistatic inline bool enic_is_err_intr(struct enic *enic, int intr) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci switch (vnic_dev_get_intr_mode(enic->vdev)) { 25862306a36Sopenharmony_ci case VNIC_DEV_INTR_MODE_INTX: 25962306a36Sopenharmony_ci return intr == ENIC_LEGACY_ERR_INTR; 26062306a36Sopenharmony_ci case VNIC_DEV_INTR_MODE_MSIX: 26162306a36Sopenharmony_ci return intr == enic_msix_err_intr(enic); 26262306a36Sopenharmony_ci case VNIC_DEV_INTR_MODE_MSI: 26362306a36Sopenharmony_ci default: 26462306a36Sopenharmony_ci return false; 26562306a36Sopenharmony_ci } 26662306a36Sopenharmony_ci} 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_cistatic inline bool enic_is_notify_intr(struct enic *enic, int intr) 26962306a36Sopenharmony_ci{ 27062306a36Sopenharmony_ci switch (vnic_dev_get_intr_mode(enic->vdev)) { 27162306a36Sopenharmony_ci case VNIC_DEV_INTR_MODE_INTX: 27262306a36Sopenharmony_ci return intr == ENIC_LEGACY_NOTIFY_INTR; 27362306a36Sopenharmony_ci case VNIC_DEV_INTR_MODE_MSIX: 27462306a36Sopenharmony_ci return intr == enic_msix_notify_intr(enic); 27562306a36Sopenharmony_ci case VNIC_DEV_INTR_MODE_MSI: 27662306a36Sopenharmony_ci default: 27762306a36Sopenharmony_ci return false; 27862306a36Sopenharmony_ci } 27962306a36Sopenharmony_ci} 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_cistatic inline int enic_dma_map_check(struct enic *enic, dma_addr_t dma_addr) 28262306a36Sopenharmony_ci{ 28362306a36Sopenharmony_ci if (unlikely(dma_mapping_error(&enic->pdev->dev, dma_addr))) { 28462306a36Sopenharmony_ci net_warn_ratelimited("%s: PCI dma mapping failed!\n", 28562306a36Sopenharmony_ci enic->netdev->name); 28662306a36Sopenharmony_ci enic->gen_stats.dma_map_error++; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci return -ENOMEM; 28962306a36Sopenharmony_ci } 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci return 0; 29262306a36Sopenharmony_ci} 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_civoid enic_reset_addr_lists(struct enic *enic); 29562306a36Sopenharmony_ciint enic_sriov_enabled(struct enic *enic); 29662306a36Sopenharmony_ciint enic_is_valid_vf(struct enic *enic, int vf); 29762306a36Sopenharmony_ciint enic_is_dynamic(struct enic *enic); 29862306a36Sopenharmony_civoid enic_set_ethtool_ops(struct net_device *netdev); 29962306a36Sopenharmony_ciint __enic_set_rsskey(struct enic *enic); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci#endif /* _ENIC_H_ */ 302