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