1004b26b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
202feda17SRajesh Borundia /*
302feda17SRajesh Borundia * QLogic qlcnic NIC Driver
402feda17SRajesh Borundia * Copyright (c) 2009-2013 QLogic Corporation
502feda17SRajesh Borundia */
602feda17SRajesh Borundia
702feda17SRajesh Borundia #ifndef _QLCNIC_83XX_SRIOV_H_
802feda17SRajesh Borundia #define _QLCNIC_83XX_SRIOV_H_
902feda17SRajesh Borundia
1002feda17SRajesh Borundia #include <linux/types.h>
1102feda17SRajesh Borundia #include <linux/pci.h>
1202feda17SRajesh Borundia
13a930a463SHarish Patil #include "qlcnic.h"
14a930a463SHarish Patil
15f8468331SRajesh Borundia extern const u32 qlcnic_83xx_reg_tbl[];
16f8468331SRajesh Borundia extern const u32 qlcnic_83xx_ext_reg_tbl[];
17f8468331SRajesh Borundia
18f197a7aaSRajesh Borundia struct qlcnic_bc_payload {
19f197a7aaSRajesh Borundia u64 payload[126];
20f197a7aaSRajesh Borundia };
21f197a7aaSRajesh Borundia
22f197a7aaSRajesh Borundia struct qlcnic_bc_hdr {
23f197a7aaSRajesh Borundia #if defined(__LITTLE_ENDIAN)
24f197a7aaSRajesh Borundia u8 version;
25f197a7aaSRajesh Borundia u8 msg_type:4;
26f197a7aaSRajesh Borundia u8 rsvd1:3;
27f197a7aaSRajesh Borundia u8 op_type:1;
28f197a7aaSRajesh Borundia u8 num_cmds;
29f197a7aaSRajesh Borundia u8 num_frags;
30f197a7aaSRajesh Borundia u8 frag_num;
31f197a7aaSRajesh Borundia u8 cmd_op;
32f197a7aaSRajesh Borundia u16 seq_id;
33f197a7aaSRajesh Borundia u64 rsvd3;
34f197a7aaSRajesh Borundia #elif defined(__BIG_ENDIAN)
35f197a7aaSRajesh Borundia u8 num_frags;
36f197a7aaSRajesh Borundia u8 num_cmds;
37f197a7aaSRajesh Borundia u8 op_type:1;
38f197a7aaSRajesh Borundia u8 rsvd1:3;
39f197a7aaSRajesh Borundia u8 msg_type:4;
40f197a7aaSRajesh Borundia u8 version;
41f197a7aaSRajesh Borundia u16 seq_id;
42f197a7aaSRajesh Borundia u8 cmd_op;
43f197a7aaSRajesh Borundia u8 frag_num;
44f197a7aaSRajesh Borundia u64 rsvd3;
45f197a7aaSRajesh Borundia #endif
46f197a7aaSRajesh Borundia };
47f197a7aaSRajesh Borundia
48f197a7aaSRajesh Borundia enum qlcnic_bc_commands {
49f197a7aaSRajesh Borundia QLCNIC_BC_CMD_CHANNEL_INIT = 0x0,
50f197a7aaSRajesh Borundia QLCNIC_BC_CMD_CHANNEL_TERM = 0x1,
5191b7282bSRajesh Borundia QLCNIC_BC_CMD_GET_ACL = 0x2,
5291b7282bSRajesh Borundia QLCNIC_BC_CMD_CFG_GUEST_VLAN = 0x3,
53f197a7aaSRajesh Borundia };
54f197a7aaSRajesh Borundia
55d747c333SRajesh Borundia #define QLCNIC_83XX_SRIOV_VF_MAX_MAC 2
56f197a7aaSRajesh Borundia #define QLC_BC_CMD 1
57f197a7aaSRajesh Borundia
58f197a7aaSRajesh Borundia struct qlcnic_trans_list {
59f197a7aaSRajesh Borundia /* Lock for manipulating list */
60f197a7aaSRajesh Borundia spinlock_t lock;
61f197a7aaSRajesh Borundia struct list_head wait_list;
62f197a7aaSRajesh Borundia int count;
63f197a7aaSRajesh Borundia };
64f197a7aaSRajesh Borundia
65f197a7aaSRajesh Borundia enum qlcnic_trans_state {
66f197a7aaSRajesh Borundia QLC_INIT = 0,
67f197a7aaSRajesh Borundia QLC_WAIT_FOR_CHANNEL_FREE,
68f197a7aaSRajesh Borundia QLC_WAIT_FOR_RESP,
69f197a7aaSRajesh Borundia QLC_ABORT,
70f197a7aaSRajesh Borundia QLC_END,
71f197a7aaSRajesh Borundia };
72f197a7aaSRajesh Borundia
73f197a7aaSRajesh Borundia struct qlcnic_bc_trans {
74f197a7aaSRajesh Borundia u8 func_id;
75f197a7aaSRajesh Borundia u8 active;
76f197a7aaSRajesh Borundia u8 curr_rsp_frag;
77f197a7aaSRajesh Borundia u8 curr_req_frag;
78f197a7aaSRajesh Borundia u16 cmd_id;
79f197a7aaSRajesh Borundia u16 req_pay_size;
80f197a7aaSRajesh Borundia u16 rsp_pay_size;
81f197a7aaSRajesh Borundia u32 trans_id;
82f197a7aaSRajesh Borundia enum qlcnic_trans_state trans_state;
83f197a7aaSRajesh Borundia struct list_head list;
84f197a7aaSRajesh Borundia struct qlcnic_bc_hdr *req_hdr;
85f197a7aaSRajesh Borundia struct qlcnic_bc_hdr *rsp_hdr;
86f197a7aaSRajesh Borundia struct qlcnic_bc_payload *req_pay;
87f197a7aaSRajesh Borundia struct qlcnic_bc_payload *rsp_pay;
88f197a7aaSRajesh Borundia struct completion resp_cmpl;
89f197a7aaSRajesh Borundia struct qlcnic_vf_info *vf;
90f197a7aaSRajesh Borundia };
91f197a7aaSRajesh Borundia
92f197a7aaSRajesh Borundia enum qlcnic_vf_state {
93f197a7aaSRajesh Borundia QLC_BC_VF_SEND = 0,
94f197a7aaSRajesh Borundia QLC_BC_VF_RECV,
95f197a7aaSRajesh Borundia QLC_BC_VF_CHANNEL,
96f197a7aaSRajesh Borundia QLC_BC_VF_STATE,
9797d8105cSRajesh Borundia QLC_BC_VF_FLR,
9897d8105cSRajesh Borundia QLC_BC_VF_SOFT_FLR,
99f197a7aaSRajesh Borundia };
100f197a7aaSRajesh Borundia
10191b7282bSRajesh Borundia enum qlcnic_vlan_mode {
10291b7282bSRajesh Borundia QLC_NO_VLAN_MODE = 0,
10391b7282bSRajesh Borundia QLC_PVID_MODE,
10491b7282bSRajesh Borundia QLC_GUEST_VLAN_MODE,
10591b7282bSRajesh Borundia };
10691b7282bSRajesh Borundia
10702feda17SRajesh Borundia struct qlcnic_resources {
10802feda17SRajesh Borundia u16 num_tx_mac_filters;
10902feda17SRajesh Borundia u16 num_rx_ucast_mac_filters;
11002feda17SRajesh Borundia u16 num_rx_mcast_mac_filters;
11102feda17SRajesh Borundia
11202feda17SRajesh Borundia u16 num_txvlan_keys;
11302feda17SRajesh Borundia
11402feda17SRajesh Borundia u16 num_rx_queues;
11502feda17SRajesh Borundia u16 num_tx_queues;
11602feda17SRajesh Borundia
11702feda17SRajesh Borundia u16 num_rx_buf_rings;
11802feda17SRajesh Borundia u16 num_rx_status_rings;
11902feda17SRajesh Borundia
12002feda17SRajesh Borundia u16 num_destip;
12102feda17SRajesh Borundia u32 num_lro_flows_supported;
12202feda17SRajesh Borundia u16 max_local_ipv6_addrs;
12302feda17SRajesh Borundia u16 max_remote_ipv6_addrs;
12402feda17SRajesh Borundia };
12502feda17SRajesh Borundia
126f197a7aaSRajesh Borundia struct qlcnic_vport {
127f197a7aaSRajesh Borundia u16 handle;
1284000e7a7SRajesh Borundia u16 max_tx_bw;
1294000e7a7SRajesh Borundia u16 min_tx_bw;
130154d0c81SManish Chopra u16 pvid;
13191b7282bSRajesh Borundia u8 vlan_mode;
13291b7282bSRajesh Borundia u8 qos;
133a80be5a5SRajesh Borundia bool spoofchk;
134f197a7aaSRajesh Borundia u8 mac[6];
135f197a7aaSRajesh Borundia };
136f197a7aaSRajesh Borundia
137f197a7aaSRajesh Borundia struct qlcnic_vf_info {
138f197a7aaSRajesh Borundia u8 pci_func;
1397cb03b23SRajesh Borundia u16 rx_ctx_id;
1407cb03b23SRajesh Borundia u16 tx_ctx_id;
141154d0c81SManish Chopra u16 *sriov_vlans;
142154d0c81SManish Chopra int num_vlan;
143f197a7aaSRajesh Borundia unsigned long state;
144f197a7aaSRajesh Borundia struct completion ch_free_cmpl;
145f197a7aaSRajesh Borundia struct work_struct trans_work;
14697d8105cSRajesh Borundia struct work_struct flr_work;
147f197a7aaSRajesh Borundia /* It synchronizes commands sent from VF */
148f197a7aaSRajesh Borundia struct mutex send_cmd_lock;
149f197a7aaSRajesh Borundia struct qlcnic_bc_trans *send_cmd;
15097d8105cSRajesh Borundia struct qlcnic_bc_trans *flr_trans;
151f197a7aaSRajesh Borundia struct qlcnic_trans_list rcv_act;
152f197a7aaSRajesh Borundia struct qlcnic_trans_list rcv_pend;
153f197a7aaSRajesh Borundia struct qlcnic_adapter *adapter;
154f197a7aaSRajesh Borundia struct qlcnic_vport *vp;
15574b7ba1aSRajesh Borundia spinlock_t vlan_list_lock; /* Lock for VLAN list */
156f197a7aaSRajesh Borundia };
157f197a7aaSRajesh Borundia
1582b10d3ecSManish Chopra struct qlcnic_async_cmd {
159e8b508efSRajesh Borundia struct list_head list;
16074b7ba1aSRajesh Borundia struct qlcnic_cmd_args *cmd;
161e8b508efSRajesh Borundia };
162e8b508efSRajesh Borundia
163f197a7aaSRajesh Borundia struct qlcnic_back_channel {
164f197a7aaSRajesh Borundia u16 trans_counter;
165f197a7aaSRajesh Borundia struct workqueue_struct *bc_trans_wq;
166e8b508efSRajesh Borundia struct workqueue_struct *bc_async_wq;
16797d8105cSRajesh Borundia struct workqueue_struct *bc_flr_wq;
1682b10d3ecSManish Chopra struct qlcnic_adapter *adapter;
1692b10d3ecSManish Chopra struct list_head async_cmd_list;
1702b10d3ecSManish Chopra struct work_struct vf_async_work;
1712b10d3ecSManish Chopra spinlock_t queue_lock; /* async_cmd_list queue lock */
172f197a7aaSRajesh Borundia };
173f197a7aaSRajesh Borundia
17402feda17SRajesh Borundia struct qlcnic_sriov {
17502feda17SRajesh Borundia u16 vp_handle;
17602feda17SRajesh Borundia u8 num_vfs;
17791b7282bSRajesh Borundia u8 any_vlan;
17891b7282bSRajesh Borundia u8 vlan_mode;
17991b7282bSRajesh Borundia u16 num_allowed_vlans;
18091b7282bSRajesh Borundia u16 *allowed_vlans;
18191b7282bSRajesh Borundia u16 vlan;
18202feda17SRajesh Borundia struct qlcnic_resources ff_max;
183f197a7aaSRajesh Borundia struct qlcnic_back_channel bc;
184f197a7aaSRajesh Borundia struct qlcnic_vf_info *vf_info;
18502feda17SRajesh Borundia };
18602feda17SRajesh Borundia
18702feda17SRajesh Borundia int qlcnic_sriov_init(struct qlcnic_adapter *, int);
18802feda17SRajesh Borundia void qlcnic_sriov_cleanup(struct qlcnic_adapter *);
18902feda17SRajesh Borundia void __qlcnic_sriov_cleanup(struct qlcnic_adapter *);
190f8468331SRajesh Borundia void qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *);
191*a72dc199SChristophe JAILLET int qlcnic_sriov_vf_init(struct qlcnic_adapter *);
192f8468331SRajesh Borundia void qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *);
193f197a7aaSRajesh Borundia int qlcnic_sriov_func_to_index(struct qlcnic_adapter *, u8);
194f197a7aaSRajesh Borundia void qlcnic_sriov_handle_bc_event(struct qlcnic_adapter *, u32);
195f197a7aaSRajesh Borundia int qlcnic_sriov_cfg_bc_intr(struct qlcnic_adapter *, u8);
196e8b508efSRajesh Borundia void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *);
19797d8105cSRajesh Borundia void qlcnic_sriov_cleanup_list(struct qlcnic_trans_list *);
19897d8105cSRajesh Borundia int __qlcnic_sriov_add_act_list(struct qlcnic_sriov *, struct qlcnic_vf_info *,
19997d8105cSRajesh Borundia struct qlcnic_bc_trans *);
2004000e7a7SRajesh Borundia int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *,
2014000e7a7SRajesh Borundia struct qlcnic_info *, u16);
20291b7282bSRajesh Borundia int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8);
203154d0c81SManish Chopra void qlcnic_sriov_free_vlans(struct qlcnic_adapter *);
20460ec7fcfSJiasheng Jiang int qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *);
205154d0c81SManish Chopra bool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *);
206154d0c81SManish Chopra void qlcnic_sriov_del_vlan_id(struct qlcnic_sriov *,
207154d0c81SManish Chopra struct qlcnic_vf_info *, u16);
208154d0c81SManish Chopra void qlcnic_sriov_add_vlan_id(struct qlcnic_sriov *,
209154d0c81SManish Chopra struct qlcnic_vf_info *, u16);
21002feda17SRajesh Borundia
qlcnic_sriov_enable_check(struct qlcnic_adapter * adapter)21102feda17SRajesh Borundia static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter)
21202feda17SRajesh Borundia {
21302feda17SRajesh Borundia return test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state) ? true : false;
21402feda17SRajesh Borundia }
21502feda17SRajesh Borundia
21602feda17SRajesh Borundia #ifdef CONFIG_QLCNIC_SRIOV
217f197a7aaSRajesh Borundia void qlcnic_sriov_pf_process_bc_cmd(struct qlcnic_adapter *,
218f197a7aaSRajesh Borundia struct qlcnic_bc_trans *,
219f197a7aaSRajesh Borundia struct qlcnic_cmd_args *);
22002feda17SRajesh Borundia void qlcnic_sriov_pf_disable(struct qlcnic_adapter *);
22102feda17SRajesh Borundia void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *);
22202feda17SRajesh Borundia int qlcnic_pci_sriov_configure(struct pci_dev *, int);
2237cb03b23SRajesh Borundia void qlcnic_pf_set_interface_id_create_rx_ctx(struct qlcnic_adapter *, u32 *);
2247cb03b23SRajesh Borundia void qlcnic_pf_set_interface_id_create_tx_ctx(struct qlcnic_adapter *, u32 *);
2257cb03b23SRajesh Borundia void qlcnic_pf_set_interface_id_del_rx_ctx(struct qlcnic_adapter *, u32 *);
2267cb03b23SRajesh Borundia void qlcnic_pf_set_interface_id_del_tx_ctx(struct qlcnic_adapter *, u32 *);
2277cb03b23SRajesh Borundia void qlcnic_pf_set_interface_id_promisc(struct qlcnic_adapter *, u32 *);
2287cb03b23SRajesh Borundia void qlcnic_pf_set_interface_id_ipaddr(struct qlcnic_adapter *, u32 *);
2297cb03b23SRajesh Borundia void qlcnic_pf_set_interface_id_macaddr(struct qlcnic_adapter *, u32 *);
23097d8105cSRajesh Borundia void qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *, struct qlcnic_vf_info *);
23197d8105cSRajesh Borundia bool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *,
23297d8105cSRajesh Borundia struct qlcnic_bc_trans *,
23397d8105cSRajesh Borundia struct qlcnic_vf_info *);
234f036e4f4SRajesh Borundia void qlcnic_sriov_pf_reset(struct qlcnic_adapter *);
235f036e4f4SRajesh Borundia int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *);
2364000e7a7SRajesh Borundia int qlcnic_sriov_set_vf_mac(struct net_device *, int, u8 *);
237ed616689SSucheta Chakraborty int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int, int);
2384000e7a7SRajesh Borundia int qlcnic_sriov_get_vf_config(struct net_device *, int ,
2394000e7a7SRajesh Borundia struct ifla_vf_info *);
24079aab093SMoshe Shemesh int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8, __be16);
241a80be5a5SRajesh Borundia int qlcnic_sriov_set_vf_spoofchk(struct net_device *, int, bool);
24202feda17SRajesh Borundia #else
qlcnic_sriov_pf_disable(struct qlcnic_adapter * adapter)24302feda17SRajesh Borundia static inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {}
qlcnic_sriov_pf_cleanup(struct qlcnic_adapter * adapter)24402feda17SRajesh Borundia static inline void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter) {}
2457cb03b23SRajesh Borundia static inline void
qlcnic_pf_set_interface_id_create_rx_ctx(struct qlcnic_adapter * adapter,u32 * int_id)2467cb03b23SRajesh Borundia qlcnic_pf_set_interface_id_create_rx_ctx(struct qlcnic_adapter *adapter,
2477cb03b23SRajesh Borundia u32 *int_id) {}
2487cb03b23SRajesh Borundia static inline void
qlcnic_pf_set_interface_id_create_tx_ctx(struct qlcnic_adapter * adapter,u32 * int_id)2497cb03b23SRajesh Borundia qlcnic_pf_set_interface_id_create_tx_ctx(struct qlcnic_adapter *adapter,
2507cb03b23SRajesh Borundia u32 *int_id) {}
2517cb03b23SRajesh Borundia static inline void
qlcnic_pf_set_interface_id_del_rx_ctx(struct qlcnic_adapter * adapter,u32 * int_id)2527cb03b23SRajesh Borundia qlcnic_pf_set_interface_id_del_rx_ctx(struct qlcnic_adapter *adapter,
2537cb03b23SRajesh Borundia u32 *int_id) {}
2547cb03b23SRajesh Borundia static inline void
qlcnic_pf_set_interface_id_del_tx_ctx(struct qlcnic_adapter * adapter,u32 * int_id)2557cb03b23SRajesh Borundia qlcnic_pf_set_interface_id_del_tx_ctx(struct qlcnic_adapter *adapter,
2567cb03b23SRajesh Borundia u32 *int_id) {}
2577cb03b23SRajesh Borundia static inline void
qlcnic_pf_set_interface_id_ipaddr(struct qlcnic_adapter * adapter,u32 * int_id)2587cb03b23SRajesh Borundia qlcnic_pf_set_interface_id_ipaddr(struct qlcnic_adapter *adapter, u32 *int_id)
2597cb03b23SRajesh Borundia {}
2607cb03b23SRajesh Borundia static inline void
qlcnic_pf_set_interface_id_macaddr(struct qlcnic_adapter * adapter,u32 * int_id)2617cb03b23SRajesh Borundia qlcnic_pf_set_interface_id_macaddr(struct qlcnic_adapter *adapter, u32 *int_id)
2627cb03b23SRajesh Borundia {}
2637cb03b23SRajesh Borundia static inline void
qlcnic_pf_set_interface_id_promisc(struct qlcnic_adapter * adapter,u32 * int_id)2647cb03b23SRajesh Borundia qlcnic_pf_set_interface_id_promisc(struct qlcnic_adapter *adapter, u32 *int_id)
2657cb03b23SRajesh Borundia {}
qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov * sriov,struct qlcnic_vf_info * vf)26697d8105cSRajesh Borundia static inline void qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *sriov,
26797d8105cSRajesh Borundia struct qlcnic_vf_info *vf) {}
qlcnic_sriov_soft_flr_check(struct qlcnic_adapter * adapter,struct qlcnic_bc_trans * trans,struct qlcnic_vf_info * vf)26897d8105cSRajesh Borundia static inline bool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *adapter,
26997d8105cSRajesh Borundia struct qlcnic_bc_trans *trans,
27097d8105cSRajesh Borundia struct qlcnic_vf_info *vf)
27197d8105cSRajesh Borundia { return false; }
qlcnic_sriov_pf_reset(struct qlcnic_adapter * adapter)272f036e4f4SRajesh Borundia static inline void qlcnic_sriov_pf_reset(struct qlcnic_adapter *adapter) {}
qlcnic_sriov_pf_reinit(struct qlcnic_adapter * adapter)273f036e4f4SRajesh Borundia static inline int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *adapter)
274f036e4f4SRajesh Borundia { return 0; }
27502feda17SRajesh Borundia #endif
27602feda17SRajesh Borundia
27702feda17SRajesh Borundia #endif
278