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