18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * QLogic qlcnic NIC Driver
48c2ecf20Sopenharmony_ci * Copyright (c) 2009-2013 QLogic Corporation
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#ifndef _QLCNIC_83XX_SRIOV_H_
88c2ecf20Sopenharmony_ci#define _QLCNIC_83XX_SRIOV_H_
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/types.h>
118c2ecf20Sopenharmony_ci#include <linux/pci.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include "qlcnic.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ciextern const u32 qlcnic_83xx_reg_tbl[];
168c2ecf20Sopenharmony_ciextern const u32 qlcnic_83xx_ext_reg_tbl[];
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistruct qlcnic_bc_payload {
198c2ecf20Sopenharmony_ci	u64 payload[126];
208c2ecf20Sopenharmony_ci};
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistruct qlcnic_bc_hdr {
238c2ecf20Sopenharmony_ci#if defined(__LITTLE_ENDIAN)
248c2ecf20Sopenharmony_ci	u8	version;
258c2ecf20Sopenharmony_ci	u8	msg_type:4;
268c2ecf20Sopenharmony_ci	u8	rsvd1:3;
278c2ecf20Sopenharmony_ci	u8	op_type:1;
288c2ecf20Sopenharmony_ci	u8	num_cmds;
298c2ecf20Sopenharmony_ci	u8	num_frags;
308c2ecf20Sopenharmony_ci	u8	frag_num;
318c2ecf20Sopenharmony_ci	u8	cmd_op;
328c2ecf20Sopenharmony_ci	u16	seq_id;
338c2ecf20Sopenharmony_ci	u64	rsvd3;
348c2ecf20Sopenharmony_ci#elif defined(__BIG_ENDIAN)
358c2ecf20Sopenharmony_ci	u8	num_frags;
368c2ecf20Sopenharmony_ci	u8	num_cmds;
378c2ecf20Sopenharmony_ci	u8	op_type:1;
388c2ecf20Sopenharmony_ci	u8	rsvd1:3;
398c2ecf20Sopenharmony_ci	u8	msg_type:4;
408c2ecf20Sopenharmony_ci	u8	version;
418c2ecf20Sopenharmony_ci	u16	seq_id;
428c2ecf20Sopenharmony_ci	u8	cmd_op;
438c2ecf20Sopenharmony_ci	u8	frag_num;
448c2ecf20Sopenharmony_ci	u64	rsvd3;
458c2ecf20Sopenharmony_ci#endif
468c2ecf20Sopenharmony_ci};
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cienum qlcnic_bc_commands {
498c2ecf20Sopenharmony_ci	QLCNIC_BC_CMD_CHANNEL_INIT = 0x0,
508c2ecf20Sopenharmony_ci	QLCNIC_BC_CMD_CHANNEL_TERM = 0x1,
518c2ecf20Sopenharmony_ci	QLCNIC_BC_CMD_GET_ACL = 0x2,
528c2ecf20Sopenharmony_ci	QLCNIC_BC_CMD_CFG_GUEST_VLAN = 0x3,
538c2ecf20Sopenharmony_ci};
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci#define QLCNIC_83XX_SRIOV_VF_MAX_MAC 2
568c2ecf20Sopenharmony_ci#define QLC_BC_CMD 1
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistruct qlcnic_trans_list {
598c2ecf20Sopenharmony_ci	/* Lock for manipulating list */
608c2ecf20Sopenharmony_ci	spinlock_t		lock;
618c2ecf20Sopenharmony_ci	struct list_head	wait_list;
628c2ecf20Sopenharmony_ci	int			count;
638c2ecf20Sopenharmony_ci};
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cienum qlcnic_trans_state {
668c2ecf20Sopenharmony_ci	QLC_INIT = 0,
678c2ecf20Sopenharmony_ci	QLC_WAIT_FOR_CHANNEL_FREE,
688c2ecf20Sopenharmony_ci	QLC_WAIT_FOR_RESP,
698c2ecf20Sopenharmony_ci	QLC_ABORT,
708c2ecf20Sopenharmony_ci	QLC_END,
718c2ecf20Sopenharmony_ci};
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cistruct qlcnic_bc_trans {
748c2ecf20Sopenharmony_ci	u8				func_id;
758c2ecf20Sopenharmony_ci	u8				active;
768c2ecf20Sopenharmony_ci	u8				curr_rsp_frag;
778c2ecf20Sopenharmony_ci	u8				curr_req_frag;
788c2ecf20Sopenharmony_ci	u16				cmd_id;
798c2ecf20Sopenharmony_ci	u16				req_pay_size;
808c2ecf20Sopenharmony_ci	u16				rsp_pay_size;
818c2ecf20Sopenharmony_ci	u32				trans_id;
828c2ecf20Sopenharmony_ci	enum qlcnic_trans_state		trans_state;
838c2ecf20Sopenharmony_ci	struct list_head		list;
848c2ecf20Sopenharmony_ci	struct qlcnic_bc_hdr		*req_hdr;
858c2ecf20Sopenharmony_ci	struct qlcnic_bc_hdr		*rsp_hdr;
868c2ecf20Sopenharmony_ci	struct qlcnic_bc_payload	*req_pay;
878c2ecf20Sopenharmony_ci	struct qlcnic_bc_payload	*rsp_pay;
888c2ecf20Sopenharmony_ci	struct completion		resp_cmpl;
898c2ecf20Sopenharmony_ci	struct qlcnic_vf_info		*vf;
908c2ecf20Sopenharmony_ci};
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_cienum qlcnic_vf_state {
938c2ecf20Sopenharmony_ci	QLC_BC_VF_SEND = 0,
948c2ecf20Sopenharmony_ci	QLC_BC_VF_RECV,
958c2ecf20Sopenharmony_ci	QLC_BC_VF_CHANNEL,
968c2ecf20Sopenharmony_ci	QLC_BC_VF_STATE,
978c2ecf20Sopenharmony_ci	QLC_BC_VF_FLR,
988c2ecf20Sopenharmony_ci	QLC_BC_VF_SOFT_FLR,
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cienum qlcnic_vlan_mode {
1028c2ecf20Sopenharmony_ci	QLC_NO_VLAN_MODE = 0,
1038c2ecf20Sopenharmony_ci	QLC_PVID_MODE,
1048c2ecf20Sopenharmony_ci	QLC_GUEST_VLAN_MODE,
1058c2ecf20Sopenharmony_ci};
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_cistruct qlcnic_resources {
1088c2ecf20Sopenharmony_ci	u16 num_tx_mac_filters;
1098c2ecf20Sopenharmony_ci	u16 num_rx_ucast_mac_filters;
1108c2ecf20Sopenharmony_ci	u16 num_rx_mcast_mac_filters;
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	u16 num_txvlan_keys;
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	u16 num_rx_queues;
1158c2ecf20Sopenharmony_ci	u16 num_tx_queues;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	u16 num_rx_buf_rings;
1188c2ecf20Sopenharmony_ci	u16 num_rx_status_rings;
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	u16 num_destip;
1218c2ecf20Sopenharmony_ci	u32 num_lro_flows_supported;
1228c2ecf20Sopenharmony_ci	u16 max_local_ipv6_addrs;
1238c2ecf20Sopenharmony_ci	u16 max_remote_ipv6_addrs;
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistruct qlcnic_vport {
1278c2ecf20Sopenharmony_ci	u16			handle;
1288c2ecf20Sopenharmony_ci	u16			max_tx_bw;
1298c2ecf20Sopenharmony_ci	u16			min_tx_bw;
1308c2ecf20Sopenharmony_ci	u16			pvid;
1318c2ecf20Sopenharmony_ci	u8			vlan_mode;
1328c2ecf20Sopenharmony_ci	u8			qos;
1338c2ecf20Sopenharmony_ci	bool			spoofchk;
1348c2ecf20Sopenharmony_ci	u8			mac[6];
1358c2ecf20Sopenharmony_ci};
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_cistruct qlcnic_vf_info {
1388c2ecf20Sopenharmony_ci	u8				pci_func;
1398c2ecf20Sopenharmony_ci	u16				rx_ctx_id;
1408c2ecf20Sopenharmony_ci	u16				tx_ctx_id;
1418c2ecf20Sopenharmony_ci	u16				*sriov_vlans;
1428c2ecf20Sopenharmony_ci	int				num_vlan;
1438c2ecf20Sopenharmony_ci	unsigned long			state;
1448c2ecf20Sopenharmony_ci	struct completion		ch_free_cmpl;
1458c2ecf20Sopenharmony_ci	struct work_struct		trans_work;
1468c2ecf20Sopenharmony_ci	struct work_struct		flr_work;
1478c2ecf20Sopenharmony_ci	/* It synchronizes commands sent from VF */
1488c2ecf20Sopenharmony_ci	struct mutex			send_cmd_lock;
1498c2ecf20Sopenharmony_ci	struct qlcnic_bc_trans		*send_cmd;
1508c2ecf20Sopenharmony_ci	struct qlcnic_bc_trans		*flr_trans;
1518c2ecf20Sopenharmony_ci	struct qlcnic_trans_list	rcv_act;
1528c2ecf20Sopenharmony_ci	struct qlcnic_trans_list	rcv_pend;
1538c2ecf20Sopenharmony_ci	struct qlcnic_adapter		*adapter;
1548c2ecf20Sopenharmony_ci	struct qlcnic_vport		*vp;
1558c2ecf20Sopenharmony_ci	spinlock_t			vlan_list_lock;	/* Lock for VLAN list */
1568c2ecf20Sopenharmony_ci};
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_cistruct qlcnic_async_cmd {
1598c2ecf20Sopenharmony_ci	struct list_head	list;
1608c2ecf20Sopenharmony_ci	struct qlcnic_cmd_args	*cmd;
1618c2ecf20Sopenharmony_ci};
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistruct qlcnic_back_channel {
1648c2ecf20Sopenharmony_ci	u16			trans_counter;
1658c2ecf20Sopenharmony_ci	struct workqueue_struct *bc_trans_wq;
1668c2ecf20Sopenharmony_ci	struct workqueue_struct *bc_async_wq;
1678c2ecf20Sopenharmony_ci	struct workqueue_struct *bc_flr_wq;
1688c2ecf20Sopenharmony_ci	struct qlcnic_adapter	*adapter;
1698c2ecf20Sopenharmony_ci	struct list_head	async_cmd_list;
1708c2ecf20Sopenharmony_ci	struct work_struct	vf_async_work;
1718c2ecf20Sopenharmony_ci	spinlock_t		queue_lock; /* async_cmd_list queue lock */
1728c2ecf20Sopenharmony_ci};
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_cistruct qlcnic_sriov {
1758c2ecf20Sopenharmony_ci	u16				vp_handle;
1768c2ecf20Sopenharmony_ci	u8				num_vfs;
1778c2ecf20Sopenharmony_ci	u8				any_vlan;
1788c2ecf20Sopenharmony_ci	u8				vlan_mode;
1798c2ecf20Sopenharmony_ci	u16				num_allowed_vlans;
1808c2ecf20Sopenharmony_ci	u16				*allowed_vlans;
1818c2ecf20Sopenharmony_ci	u16				vlan;
1828c2ecf20Sopenharmony_ci	struct qlcnic_resources		ff_max;
1838c2ecf20Sopenharmony_ci	struct qlcnic_back_channel	bc;
1848c2ecf20Sopenharmony_ci	struct qlcnic_vf_info		*vf_info;
1858c2ecf20Sopenharmony_ci};
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ciint qlcnic_sriov_init(struct qlcnic_adapter *, int);
1888c2ecf20Sopenharmony_civoid qlcnic_sriov_cleanup(struct qlcnic_adapter *);
1898c2ecf20Sopenharmony_civoid __qlcnic_sriov_cleanup(struct qlcnic_adapter *);
1908c2ecf20Sopenharmony_civoid qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *);
1918c2ecf20Sopenharmony_ciint qlcnic_sriov_vf_init(struct qlcnic_adapter *, int);
1928c2ecf20Sopenharmony_civoid qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *);
1938c2ecf20Sopenharmony_ciint qlcnic_sriov_func_to_index(struct qlcnic_adapter *, u8);
1948c2ecf20Sopenharmony_civoid qlcnic_sriov_handle_bc_event(struct qlcnic_adapter *, u32);
1958c2ecf20Sopenharmony_ciint qlcnic_sriov_cfg_bc_intr(struct qlcnic_adapter *, u8);
1968c2ecf20Sopenharmony_civoid qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *);
1978c2ecf20Sopenharmony_civoid qlcnic_sriov_cleanup_list(struct qlcnic_trans_list *);
1988c2ecf20Sopenharmony_ciint __qlcnic_sriov_add_act_list(struct qlcnic_sriov *, struct qlcnic_vf_info *,
1998c2ecf20Sopenharmony_ci				struct qlcnic_bc_trans *);
2008c2ecf20Sopenharmony_ciint qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *,
2018c2ecf20Sopenharmony_ci				   struct qlcnic_info *, u16);
2028c2ecf20Sopenharmony_ciint qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8);
2038c2ecf20Sopenharmony_civoid qlcnic_sriov_free_vlans(struct qlcnic_adapter *);
2048c2ecf20Sopenharmony_ciint qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *);
2058c2ecf20Sopenharmony_cibool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *);
2068c2ecf20Sopenharmony_civoid qlcnic_sriov_del_vlan_id(struct qlcnic_sriov *,
2078c2ecf20Sopenharmony_ci			      struct qlcnic_vf_info *, u16);
2088c2ecf20Sopenharmony_civoid qlcnic_sriov_add_vlan_id(struct qlcnic_sriov *,
2098c2ecf20Sopenharmony_ci			      struct qlcnic_vf_info *, u16);
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_cistatic inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter)
2128c2ecf20Sopenharmony_ci{
2138c2ecf20Sopenharmony_ci	return test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state) ? true : false;
2148c2ecf20Sopenharmony_ci}
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci#ifdef CONFIG_QLCNIC_SRIOV
2178c2ecf20Sopenharmony_civoid qlcnic_sriov_pf_process_bc_cmd(struct qlcnic_adapter *,
2188c2ecf20Sopenharmony_ci				    struct qlcnic_bc_trans *,
2198c2ecf20Sopenharmony_ci				    struct qlcnic_cmd_args *);
2208c2ecf20Sopenharmony_civoid qlcnic_sriov_pf_disable(struct qlcnic_adapter *);
2218c2ecf20Sopenharmony_civoid qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *);
2228c2ecf20Sopenharmony_ciint qlcnic_pci_sriov_configure(struct pci_dev *, int);
2238c2ecf20Sopenharmony_civoid qlcnic_pf_set_interface_id_create_rx_ctx(struct qlcnic_adapter *, u32 *);
2248c2ecf20Sopenharmony_civoid qlcnic_pf_set_interface_id_create_tx_ctx(struct qlcnic_adapter *, u32 *);
2258c2ecf20Sopenharmony_civoid qlcnic_pf_set_interface_id_del_rx_ctx(struct qlcnic_adapter *, u32 *);
2268c2ecf20Sopenharmony_civoid qlcnic_pf_set_interface_id_del_tx_ctx(struct qlcnic_adapter *, u32 *);
2278c2ecf20Sopenharmony_civoid qlcnic_pf_set_interface_id_promisc(struct qlcnic_adapter *, u32 *);
2288c2ecf20Sopenharmony_civoid qlcnic_pf_set_interface_id_ipaddr(struct qlcnic_adapter *, u32 *);
2298c2ecf20Sopenharmony_civoid qlcnic_pf_set_interface_id_macaddr(struct qlcnic_adapter *, u32 *);
2308c2ecf20Sopenharmony_civoid qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *, struct qlcnic_vf_info *);
2318c2ecf20Sopenharmony_cibool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *,
2328c2ecf20Sopenharmony_ci				 struct qlcnic_bc_trans *,
2338c2ecf20Sopenharmony_ci				 struct qlcnic_vf_info *);
2348c2ecf20Sopenharmony_civoid qlcnic_sriov_pf_reset(struct qlcnic_adapter *);
2358c2ecf20Sopenharmony_ciint qlcnic_sriov_pf_reinit(struct qlcnic_adapter *);
2368c2ecf20Sopenharmony_ciint qlcnic_sriov_set_vf_mac(struct net_device *, int, u8 *);
2378c2ecf20Sopenharmony_ciint qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int, int);
2388c2ecf20Sopenharmony_ciint qlcnic_sriov_get_vf_config(struct net_device *, int ,
2398c2ecf20Sopenharmony_ci			       struct ifla_vf_info *);
2408c2ecf20Sopenharmony_ciint qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8, __be16);
2418c2ecf20Sopenharmony_ciint qlcnic_sriov_set_vf_spoofchk(struct net_device *, int, bool);
2428c2ecf20Sopenharmony_ci#else
2438c2ecf20Sopenharmony_cistatic inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {}
2448c2ecf20Sopenharmony_cistatic inline void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter) {}
2458c2ecf20Sopenharmony_cistatic inline void
2468c2ecf20Sopenharmony_ciqlcnic_pf_set_interface_id_create_rx_ctx(struct qlcnic_adapter *adapter,
2478c2ecf20Sopenharmony_ci					 u32 *int_id) {}
2488c2ecf20Sopenharmony_cistatic inline void
2498c2ecf20Sopenharmony_ciqlcnic_pf_set_interface_id_create_tx_ctx(struct qlcnic_adapter *adapter,
2508c2ecf20Sopenharmony_ci					 u32 *int_id) {}
2518c2ecf20Sopenharmony_cistatic inline void
2528c2ecf20Sopenharmony_ciqlcnic_pf_set_interface_id_del_rx_ctx(struct qlcnic_adapter *adapter,
2538c2ecf20Sopenharmony_ci				      u32 *int_id) {}
2548c2ecf20Sopenharmony_cistatic inline void
2558c2ecf20Sopenharmony_ciqlcnic_pf_set_interface_id_del_tx_ctx(struct qlcnic_adapter *adapter,
2568c2ecf20Sopenharmony_ci				      u32 *int_id) {}
2578c2ecf20Sopenharmony_cistatic inline void
2588c2ecf20Sopenharmony_ciqlcnic_pf_set_interface_id_ipaddr(struct qlcnic_adapter *adapter, u32 *int_id)
2598c2ecf20Sopenharmony_ci{}
2608c2ecf20Sopenharmony_cistatic inline void
2618c2ecf20Sopenharmony_ciqlcnic_pf_set_interface_id_macaddr(struct qlcnic_adapter *adapter, u32 *int_id)
2628c2ecf20Sopenharmony_ci{}
2638c2ecf20Sopenharmony_cistatic inline void
2648c2ecf20Sopenharmony_ciqlcnic_pf_set_interface_id_promisc(struct qlcnic_adapter *adapter, u32 *int_id)
2658c2ecf20Sopenharmony_ci{}
2668c2ecf20Sopenharmony_cistatic inline void qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *sriov,
2678c2ecf20Sopenharmony_ci					      struct qlcnic_vf_info *vf) {}
2688c2ecf20Sopenharmony_cistatic inline bool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *adapter,
2698c2ecf20Sopenharmony_ci					       struct qlcnic_bc_trans *trans,
2708c2ecf20Sopenharmony_ci					       struct qlcnic_vf_info *vf)
2718c2ecf20Sopenharmony_ci{ return false; }
2728c2ecf20Sopenharmony_cistatic inline void qlcnic_sriov_pf_reset(struct qlcnic_adapter *adapter) {}
2738c2ecf20Sopenharmony_cistatic inline int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *adapter)
2748c2ecf20Sopenharmony_ci{ return 0; }
2758c2ecf20Sopenharmony_ci#endif
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci#endif
278