162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * QLogic qlcnic NIC Driver
462306a36Sopenharmony_ci * Copyright (c) 2009-2013 QLogic Corporation
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef _QLCNIC_83XX_SRIOV_H_
862306a36Sopenharmony_ci#define _QLCNIC_83XX_SRIOV_H_
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/types.h>
1162306a36Sopenharmony_ci#include <linux/pci.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include "qlcnic.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ciextern const u32 qlcnic_83xx_reg_tbl[];
1662306a36Sopenharmony_ciextern const u32 qlcnic_83xx_ext_reg_tbl[];
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistruct qlcnic_bc_payload {
1962306a36Sopenharmony_ci	u64 payload[126];
2062306a36Sopenharmony_ci};
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistruct qlcnic_bc_hdr {
2362306a36Sopenharmony_ci#if defined(__LITTLE_ENDIAN)
2462306a36Sopenharmony_ci	u8	version;
2562306a36Sopenharmony_ci	u8	msg_type:4;
2662306a36Sopenharmony_ci	u8	rsvd1:3;
2762306a36Sopenharmony_ci	u8	op_type:1;
2862306a36Sopenharmony_ci	u8	num_cmds;
2962306a36Sopenharmony_ci	u8	num_frags;
3062306a36Sopenharmony_ci	u8	frag_num;
3162306a36Sopenharmony_ci	u8	cmd_op;
3262306a36Sopenharmony_ci	u16	seq_id;
3362306a36Sopenharmony_ci	u64	rsvd3;
3462306a36Sopenharmony_ci#elif defined(__BIG_ENDIAN)
3562306a36Sopenharmony_ci	u8	num_frags;
3662306a36Sopenharmony_ci	u8	num_cmds;
3762306a36Sopenharmony_ci	u8	op_type:1;
3862306a36Sopenharmony_ci	u8	rsvd1:3;
3962306a36Sopenharmony_ci	u8	msg_type:4;
4062306a36Sopenharmony_ci	u8	version;
4162306a36Sopenharmony_ci	u16	seq_id;
4262306a36Sopenharmony_ci	u8	cmd_op;
4362306a36Sopenharmony_ci	u8	frag_num;
4462306a36Sopenharmony_ci	u64	rsvd3;
4562306a36Sopenharmony_ci#endif
4662306a36Sopenharmony_ci};
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cienum qlcnic_bc_commands {
4962306a36Sopenharmony_ci	QLCNIC_BC_CMD_CHANNEL_INIT = 0x0,
5062306a36Sopenharmony_ci	QLCNIC_BC_CMD_CHANNEL_TERM = 0x1,
5162306a36Sopenharmony_ci	QLCNIC_BC_CMD_GET_ACL = 0x2,
5262306a36Sopenharmony_ci	QLCNIC_BC_CMD_CFG_GUEST_VLAN = 0x3,
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci#define QLCNIC_83XX_SRIOV_VF_MAX_MAC 2
5662306a36Sopenharmony_ci#define QLC_BC_CMD 1
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_cistruct qlcnic_trans_list {
5962306a36Sopenharmony_ci	/* Lock for manipulating list */
6062306a36Sopenharmony_ci	spinlock_t		lock;
6162306a36Sopenharmony_ci	struct list_head	wait_list;
6262306a36Sopenharmony_ci	int			count;
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cienum qlcnic_trans_state {
6662306a36Sopenharmony_ci	QLC_INIT = 0,
6762306a36Sopenharmony_ci	QLC_WAIT_FOR_CHANNEL_FREE,
6862306a36Sopenharmony_ci	QLC_WAIT_FOR_RESP,
6962306a36Sopenharmony_ci	QLC_ABORT,
7062306a36Sopenharmony_ci	QLC_END,
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cistruct qlcnic_bc_trans {
7462306a36Sopenharmony_ci	u8				func_id;
7562306a36Sopenharmony_ci	u8				active;
7662306a36Sopenharmony_ci	u8				curr_rsp_frag;
7762306a36Sopenharmony_ci	u8				curr_req_frag;
7862306a36Sopenharmony_ci	u16				cmd_id;
7962306a36Sopenharmony_ci	u16				req_pay_size;
8062306a36Sopenharmony_ci	u16				rsp_pay_size;
8162306a36Sopenharmony_ci	u32				trans_id;
8262306a36Sopenharmony_ci	enum qlcnic_trans_state		trans_state;
8362306a36Sopenharmony_ci	struct list_head		list;
8462306a36Sopenharmony_ci	struct qlcnic_bc_hdr		*req_hdr;
8562306a36Sopenharmony_ci	struct qlcnic_bc_hdr		*rsp_hdr;
8662306a36Sopenharmony_ci	struct qlcnic_bc_payload	*req_pay;
8762306a36Sopenharmony_ci	struct qlcnic_bc_payload	*rsp_pay;
8862306a36Sopenharmony_ci	struct completion		resp_cmpl;
8962306a36Sopenharmony_ci	struct qlcnic_vf_info		*vf;
9062306a36Sopenharmony_ci};
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cienum qlcnic_vf_state {
9362306a36Sopenharmony_ci	QLC_BC_VF_SEND = 0,
9462306a36Sopenharmony_ci	QLC_BC_VF_RECV,
9562306a36Sopenharmony_ci	QLC_BC_VF_CHANNEL,
9662306a36Sopenharmony_ci	QLC_BC_VF_STATE,
9762306a36Sopenharmony_ci	QLC_BC_VF_FLR,
9862306a36Sopenharmony_ci	QLC_BC_VF_SOFT_FLR,
9962306a36Sopenharmony_ci};
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_cienum qlcnic_vlan_mode {
10262306a36Sopenharmony_ci	QLC_NO_VLAN_MODE = 0,
10362306a36Sopenharmony_ci	QLC_PVID_MODE,
10462306a36Sopenharmony_ci	QLC_GUEST_VLAN_MODE,
10562306a36Sopenharmony_ci};
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistruct qlcnic_resources {
10862306a36Sopenharmony_ci	u16 num_tx_mac_filters;
10962306a36Sopenharmony_ci	u16 num_rx_ucast_mac_filters;
11062306a36Sopenharmony_ci	u16 num_rx_mcast_mac_filters;
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	u16 num_txvlan_keys;
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	u16 num_rx_queues;
11562306a36Sopenharmony_ci	u16 num_tx_queues;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	u16 num_rx_buf_rings;
11862306a36Sopenharmony_ci	u16 num_rx_status_rings;
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	u16 num_destip;
12162306a36Sopenharmony_ci	u32 num_lro_flows_supported;
12262306a36Sopenharmony_ci	u16 max_local_ipv6_addrs;
12362306a36Sopenharmony_ci	u16 max_remote_ipv6_addrs;
12462306a36Sopenharmony_ci};
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_cistruct qlcnic_vport {
12762306a36Sopenharmony_ci	u16			handle;
12862306a36Sopenharmony_ci	u16			max_tx_bw;
12962306a36Sopenharmony_ci	u16			min_tx_bw;
13062306a36Sopenharmony_ci	u16			pvid;
13162306a36Sopenharmony_ci	u8			vlan_mode;
13262306a36Sopenharmony_ci	u8			qos;
13362306a36Sopenharmony_ci	bool			spoofchk;
13462306a36Sopenharmony_ci	u8			mac[6];
13562306a36Sopenharmony_ci};
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cistruct qlcnic_vf_info {
13862306a36Sopenharmony_ci	u8				pci_func;
13962306a36Sopenharmony_ci	u16				rx_ctx_id;
14062306a36Sopenharmony_ci	u16				tx_ctx_id;
14162306a36Sopenharmony_ci	u16				*sriov_vlans;
14262306a36Sopenharmony_ci	int				num_vlan;
14362306a36Sopenharmony_ci	unsigned long			state;
14462306a36Sopenharmony_ci	struct completion		ch_free_cmpl;
14562306a36Sopenharmony_ci	struct work_struct		trans_work;
14662306a36Sopenharmony_ci	struct work_struct		flr_work;
14762306a36Sopenharmony_ci	/* It synchronizes commands sent from VF */
14862306a36Sopenharmony_ci	struct mutex			send_cmd_lock;
14962306a36Sopenharmony_ci	struct qlcnic_bc_trans		*send_cmd;
15062306a36Sopenharmony_ci	struct qlcnic_bc_trans		*flr_trans;
15162306a36Sopenharmony_ci	struct qlcnic_trans_list	rcv_act;
15262306a36Sopenharmony_ci	struct qlcnic_trans_list	rcv_pend;
15362306a36Sopenharmony_ci	struct qlcnic_adapter		*adapter;
15462306a36Sopenharmony_ci	struct qlcnic_vport		*vp;
15562306a36Sopenharmony_ci	spinlock_t			vlan_list_lock;	/* Lock for VLAN list */
15662306a36Sopenharmony_ci};
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistruct qlcnic_async_cmd {
15962306a36Sopenharmony_ci	struct list_head	list;
16062306a36Sopenharmony_ci	struct qlcnic_cmd_args	*cmd;
16162306a36Sopenharmony_ci};
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistruct qlcnic_back_channel {
16462306a36Sopenharmony_ci	u16			trans_counter;
16562306a36Sopenharmony_ci	struct workqueue_struct *bc_trans_wq;
16662306a36Sopenharmony_ci	struct workqueue_struct *bc_async_wq;
16762306a36Sopenharmony_ci	struct workqueue_struct *bc_flr_wq;
16862306a36Sopenharmony_ci	struct qlcnic_adapter	*adapter;
16962306a36Sopenharmony_ci	struct list_head	async_cmd_list;
17062306a36Sopenharmony_ci	struct work_struct	vf_async_work;
17162306a36Sopenharmony_ci	spinlock_t		queue_lock; /* async_cmd_list queue lock */
17262306a36Sopenharmony_ci};
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_cistruct qlcnic_sriov {
17562306a36Sopenharmony_ci	u16				vp_handle;
17662306a36Sopenharmony_ci	u8				num_vfs;
17762306a36Sopenharmony_ci	u8				any_vlan;
17862306a36Sopenharmony_ci	u8				vlan_mode;
17962306a36Sopenharmony_ci	u16				num_allowed_vlans;
18062306a36Sopenharmony_ci	u16				*allowed_vlans;
18162306a36Sopenharmony_ci	u16				vlan;
18262306a36Sopenharmony_ci	struct qlcnic_resources		ff_max;
18362306a36Sopenharmony_ci	struct qlcnic_back_channel	bc;
18462306a36Sopenharmony_ci	struct qlcnic_vf_info		*vf_info;
18562306a36Sopenharmony_ci};
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ciint qlcnic_sriov_init(struct qlcnic_adapter *, int);
18862306a36Sopenharmony_civoid qlcnic_sriov_cleanup(struct qlcnic_adapter *);
18962306a36Sopenharmony_civoid __qlcnic_sriov_cleanup(struct qlcnic_adapter *);
19062306a36Sopenharmony_civoid qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *);
19162306a36Sopenharmony_ciint qlcnic_sriov_vf_init(struct qlcnic_adapter *);
19262306a36Sopenharmony_civoid qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *);
19362306a36Sopenharmony_ciint qlcnic_sriov_func_to_index(struct qlcnic_adapter *, u8);
19462306a36Sopenharmony_civoid qlcnic_sriov_handle_bc_event(struct qlcnic_adapter *, u32);
19562306a36Sopenharmony_ciint qlcnic_sriov_cfg_bc_intr(struct qlcnic_adapter *, u8);
19662306a36Sopenharmony_civoid qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *);
19762306a36Sopenharmony_civoid qlcnic_sriov_cleanup_list(struct qlcnic_trans_list *);
19862306a36Sopenharmony_ciint __qlcnic_sriov_add_act_list(struct qlcnic_sriov *, struct qlcnic_vf_info *,
19962306a36Sopenharmony_ci				struct qlcnic_bc_trans *);
20062306a36Sopenharmony_ciint qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *,
20162306a36Sopenharmony_ci				   struct qlcnic_info *, u16);
20262306a36Sopenharmony_ciint qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8);
20362306a36Sopenharmony_civoid qlcnic_sriov_free_vlans(struct qlcnic_adapter *);
20462306a36Sopenharmony_ciint qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *);
20562306a36Sopenharmony_cibool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *);
20662306a36Sopenharmony_civoid qlcnic_sriov_del_vlan_id(struct qlcnic_sriov *,
20762306a36Sopenharmony_ci			      struct qlcnic_vf_info *, u16);
20862306a36Sopenharmony_civoid qlcnic_sriov_add_vlan_id(struct qlcnic_sriov *,
20962306a36Sopenharmony_ci			      struct qlcnic_vf_info *, u16);
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_cistatic inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	return test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state) ? true : false;
21462306a36Sopenharmony_ci}
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci#ifdef CONFIG_QLCNIC_SRIOV
21762306a36Sopenharmony_civoid qlcnic_sriov_pf_process_bc_cmd(struct qlcnic_adapter *,
21862306a36Sopenharmony_ci				    struct qlcnic_bc_trans *,
21962306a36Sopenharmony_ci				    struct qlcnic_cmd_args *);
22062306a36Sopenharmony_civoid qlcnic_sriov_pf_disable(struct qlcnic_adapter *);
22162306a36Sopenharmony_civoid qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *);
22262306a36Sopenharmony_ciint qlcnic_pci_sriov_configure(struct pci_dev *, int);
22362306a36Sopenharmony_civoid qlcnic_pf_set_interface_id_create_rx_ctx(struct qlcnic_adapter *, u32 *);
22462306a36Sopenharmony_civoid qlcnic_pf_set_interface_id_create_tx_ctx(struct qlcnic_adapter *, u32 *);
22562306a36Sopenharmony_civoid qlcnic_pf_set_interface_id_del_rx_ctx(struct qlcnic_adapter *, u32 *);
22662306a36Sopenharmony_civoid qlcnic_pf_set_interface_id_del_tx_ctx(struct qlcnic_adapter *, u32 *);
22762306a36Sopenharmony_civoid qlcnic_pf_set_interface_id_promisc(struct qlcnic_adapter *, u32 *);
22862306a36Sopenharmony_civoid qlcnic_pf_set_interface_id_ipaddr(struct qlcnic_adapter *, u32 *);
22962306a36Sopenharmony_civoid qlcnic_pf_set_interface_id_macaddr(struct qlcnic_adapter *, u32 *);
23062306a36Sopenharmony_civoid qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *, struct qlcnic_vf_info *);
23162306a36Sopenharmony_cibool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *,
23262306a36Sopenharmony_ci				 struct qlcnic_bc_trans *,
23362306a36Sopenharmony_ci				 struct qlcnic_vf_info *);
23462306a36Sopenharmony_civoid qlcnic_sriov_pf_reset(struct qlcnic_adapter *);
23562306a36Sopenharmony_ciint qlcnic_sriov_pf_reinit(struct qlcnic_adapter *);
23662306a36Sopenharmony_ciint qlcnic_sriov_set_vf_mac(struct net_device *, int, u8 *);
23762306a36Sopenharmony_ciint qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int, int);
23862306a36Sopenharmony_ciint qlcnic_sriov_get_vf_config(struct net_device *, int ,
23962306a36Sopenharmony_ci			       struct ifla_vf_info *);
24062306a36Sopenharmony_ciint qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8, __be16);
24162306a36Sopenharmony_ciint qlcnic_sriov_set_vf_spoofchk(struct net_device *, int, bool);
24262306a36Sopenharmony_ci#else
24362306a36Sopenharmony_cistatic inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {}
24462306a36Sopenharmony_cistatic inline void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter) {}
24562306a36Sopenharmony_cistatic inline void
24662306a36Sopenharmony_ciqlcnic_pf_set_interface_id_create_rx_ctx(struct qlcnic_adapter *adapter,
24762306a36Sopenharmony_ci					 u32 *int_id) {}
24862306a36Sopenharmony_cistatic inline void
24962306a36Sopenharmony_ciqlcnic_pf_set_interface_id_create_tx_ctx(struct qlcnic_adapter *adapter,
25062306a36Sopenharmony_ci					 u32 *int_id) {}
25162306a36Sopenharmony_cistatic inline void
25262306a36Sopenharmony_ciqlcnic_pf_set_interface_id_del_rx_ctx(struct qlcnic_adapter *adapter,
25362306a36Sopenharmony_ci				      u32 *int_id) {}
25462306a36Sopenharmony_cistatic inline void
25562306a36Sopenharmony_ciqlcnic_pf_set_interface_id_del_tx_ctx(struct qlcnic_adapter *adapter,
25662306a36Sopenharmony_ci				      u32 *int_id) {}
25762306a36Sopenharmony_cistatic inline void
25862306a36Sopenharmony_ciqlcnic_pf_set_interface_id_ipaddr(struct qlcnic_adapter *adapter, u32 *int_id)
25962306a36Sopenharmony_ci{}
26062306a36Sopenharmony_cistatic inline void
26162306a36Sopenharmony_ciqlcnic_pf_set_interface_id_macaddr(struct qlcnic_adapter *adapter, u32 *int_id)
26262306a36Sopenharmony_ci{}
26362306a36Sopenharmony_cistatic inline void
26462306a36Sopenharmony_ciqlcnic_pf_set_interface_id_promisc(struct qlcnic_adapter *adapter, u32 *int_id)
26562306a36Sopenharmony_ci{}
26662306a36Sopenharmony_cistatic inline void qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *sriov,
26762306a36Sopenharmony_ci					      struct qlcnic_vf_info *vf) {}
26862306a36Sopenharmony_cistatic inline bool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *adapter,
26962306a36Sopenharmony_ci					       struct qlcnic_bc_trans *trans,
27062306a36Sopenharmony_ci					       struct qlcnic_vf_info *vf)
27162306a36Sopenharmony_ci{ return false; }
27262306a36Sopenharmony_cistatic inline void qlcnic_sriov_pf_reset(struct qlcnic_adapter *adapter) {}
27362306a36Sopenharmony_cistatic inline int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *adapter)
27462306a36Sopenharmony_ci{ return 0; }
27562306a36Sopenharmony_ci#endif
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci#endif
278