ecore_sriov.h revision 337517
1/*
2 * Copyright (c) 2017-2018 Cavium, Inc.
3 * All rights reserved.
4 *
5 *  Redistribution and use in source and binary forms, with or without
6 *  modification, are permitted provided that the following conditions
7 *  are met:
8 *
9 *  1. Redistributions of source code must retain the above copyright
10 *     notice, this list of conditions and the following disclaimer.
11 *  2. Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 *
15 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 *  POSSIBILITY OF SUCH DAMAGE.
26 *
27 * $FreeBSD: stable/11/sys/dev/qlnx/qlnxe/ecore_sriov.h 337517 2018-08-09 01:17:35Z davidcs $
28 *
29 */
30
31#ifndef __ECORE_SRIOV_H__
32#define __ECORE_SRIOV_H__
33
34#include "ecore_status.h"
35#include "ecore_vfpf_if.h"
36#include "ecore_iov_api.h"
37#include "ecore_hsi_common.h"
38#include "ecore_l2.h"
39
40#define ECORE_ETH_MAX_VF_NUM_VLAN_FILTERS \
41	(MAX_NUM_VFS_E4 * ECORE_ETH_VF_NUM_VLAN_FILTERS)
42
43/* Represents a full message. Both the request filled by VF
44 * and the response filled by the PF. The VF needs one copy
45 * of this message, it fills the request part and sends it to
46 * the PF. The PF will copy the response to the response part for
47 * the VF to later read it. The PF needs to hold a message like this
48 * per VF, the request that is copied to the PF is placed in the
49 * request size, and the response is filled by the PF before sending
50 * it to the VF.
51 */
52struct ecore_vf_mbx_msg {
53	union vfpf_tlvs req;
54	union pfvf_tlvs resp;
55};
56
57/* This mailbox is maintained per VF in its PF
58 * contains all information required for sending / receiving
59 * a message
60 */
61struct ecore_iov_vf_mbx {
62	union vfpf_tlvs		*req_virt;
63	dma_addr_t		req_phys;
64	union pfvf_tlvs		*reply_virt;
65	dma_addr_t		reply_phys;
66
67	/* Address in VF where a pending message is located */
68	dma_addr_t		pending_req;
69
70	/* Message from VF awaits handling */
71	bool			b_pending_msg;
72
73	u8 *offset;
74
75#ifdef CONFIG_ECORE_SW_CHANNEL
76	struct ecore_iov_sw_mbx sw_mbx;
77#endif
78
79	/* VF GPA address */
80	u32			vf_addr_lo;
81	u32			vf_addr_hi;
82
83	struct vfpf_first_tlv	first_tlv;	/* saved VF request header */
84
85	u8			flags;
86#define VF_MSG_INPROCESS	0x1	/* failsafe - the FW should prevent
87					 * more then one pending msg
88					 */
89};
90
91#define ECORE_IOV_LEGACY_QID_RX (0)
92#define ECORE_IOV_LEGACY_QID_TX (1)
93#define ECORE_IOV_QID_INVALID (0xFE)
94
95struct ecore_vf_queue_cid {
96	bool b_is_tx;
97	struct ecore_queue_cid *p_cid;
98};
99
100/* Describes a qzone associated with the VF */
101struct ecore_vf_queue {
102	/* Input from upper-layer, mapping relateive queue to queue-zone */
103	u16 fw_rx_qid;
104	u16 fw_tx_qid;
105
106	struct ecore_vf_queue_cid cids[MAX_QUEUES_PER_QZONE];
107};
108
109enum vf_state {
110	VF_FREE		= 0,	/* VF ready to be acquired holds no resc */
111	VF_ACQUIRED	= 1,	/* VF, aquired, but not initalized */
112	VF_ENABLED	= 2,	/* VF, Enabled */
113	VF_RESET	= 3,	/* VF, FLR'd, pending cleanup */
114	VF_STOPPED      = 4     /* VF, Stopped */
115};
116
117struct ecore_vf_vlan_shadow {
118	bool used;
119	u16 vid;
120};
121
122struct ecore_vf_shadow_config {
123	/* Shadow copy of all guest vlans */
124	struct ecore_vf_vlan_shadow vlans[ECORE_ETH_VF_NUM_VLAN_FILTERS + 1];
125
126	/* Shadow copy of all configured MACs; Empty if forcing MACs */
127	u8 macs[ECORE_ETH_VF_NUM_MAC_FILTERS][ETH_ALEN];
128	u8 inner_vlan_removal;
129};
130
131/* PFs maintain an array of this structure, per VF */
132struct ecore_vf_info {
133	struct ecore_iov_vf_mbx vf_mbx;
134	enum vf_state state;
135	bool b_init;
136	bool b_malicious;
137	u8			to_disable;
138
139	struct ecore_bulletin	bulletin;
140	dma_addr_t		vf_bulletin;
141
142#ifdef CONFIG_ECORE_SW_CHANNEL
143	/* Determine whether PF communicate with VF using HW/SW channel */
144	bool	b_hw_channel;
145#endif
146
147	/* PF saves a copy of the last VF acquire message */
148	struct vfpf_acquire_tlv acquire;
149
150	u32			concrete_fid;
151	u16			opaque_fid;
152	u16			mtu;
153
154	u8			vport_id;
155	u8			rss_eng_id;
156	u8			relative_vf_id;
157	u8			abs_vf_id;
158#define ECORE_VF_ABS_ID(p_hwfn, p_vf)	(ECORE_PATH_ID(p_hwfn) ? \
159					 (p_vf)->abs_vf_id + MAX_NUM_VFS_BB : \
160					 (p_vf)->abs_vf_id)
161
162	u8			vport_instance; /* Number of active vports */
163	u8			num_rxqs;
164	u8			num_txqs;
165
166	u16			rx_coal;
167	u16			tx_coal;
168
169	u8			num_sbs;
170
171	u8			num_mac_filters;
172	u8			num_vlan_filters;
173
174	struct ecore_vf_queue	vf_queues[ECORE_MAX_VF_CHAINS_PER_PF];
175	u16			igu_sbs[ECORE_MAX_VF_CHAINS_PER_PF];
176
177	/* TODO - Only windows is using it - should be removed */
178	u8 was_malicious;
179	u8 num_active_rxqs;
180	void *ctx;
181	struct ecore_public_vf_info p_vf_info;
182	bool spoof_chk;		/* Current configured on HW */
183	bool req_spoofchk_val;  /* Requested value */
184
185	/* Stores the configuration requested by VF */
186	struct ecore_vf_shadow_config shadow_config;
187
188	/* A bitfield using bulletin's valid-map bits, used to indicate
189	 * which of the bulletin board features have been configured.
190	 */
191	u64 configured_features;
192#define ECORE_IOV_CONFIGURED_FEATURES_MASK	((1 << MAC_ADDR_FORCED) | \
193						 (1 << VLAN_ADDR_FORCED))
194};
195
196/* This structure is part of ecore_hwfn and used only for PFs that have sriov
197 * capability enabled.
198 */
199struct ecore_pf_iov {
200	struct ecore_vf_info	vfs_array[MAX_NUM_VFS_E4];
201	u64			pending_flr[ECORE_VF_ARRAY_LENGTH];
202
203#ifndef REMOVE_DBG
204	/* This doesn't serve anything functionally, but it makes windows
205	 * debugging of IOV related issues easier.
206	 */
207	u64			active_vfs[ECORE_VF_ARRAY_LENGTH];
208#endif
209
210	/* Allocate message address continuosuly and split to each VF */
211	void			*mbx_msg_virt_addr;
212	dma_addr_t		mbx_msg_phys_addr;
213	u32			mbx_msg_size;
214	void			*mbx_reply_virt_addr;
215	dma_addr_t		mbx_reply_phys_addr;
216	u32			mbx_reply_size;
217	void			*p_bulletins;
218	dma_addr_t		bulletins_phys;
219	u32			bulletins_size;
220};
221
222#ifdef CONFIG_ECORE_SRIOV
223/**
224 * @brief Read sriov related information and allocated resources
225 *  reads from configuraiton space, shmem, etc.
226 *
227 * @param p_hwfn
228 *
229 * @return enum _ecore_status_t
230 */
231enum _ecore_status_t ecore_iov_hw_info(struct ecore_hwfn *p_hwfn);
232
233/**
234 * @brief ecore_add_tlv - place a given tlv on the tlv buffer at next offset
235 *
236 * @param offset
237 * @param type
238 * @param length
239 *
240 * @return pointer to the newly placed tlv
241 */
242void *ecore_add_tlv(u8 **offset, u16 type, u16 length);
243
244/**
245 * @brief list the types and lengths of the tlvs on the buffer
246 *
247 * @param p_hwfn
248 * @param tlvs_list
249 */
250void ecore_dp_tlv_list(struct ecore_hwfn *p_hwfn,
251		       void *tlvs_list);
252
253/**
254 * @brief ecore_iov_alloc - allocate sriov related resources
255 *
256 * @param p_hwfn
257 *
258 * @return enum _ecore_status_t
259 */
260enum _ecore_status_t ecore_iov_alloc(struct ecore_hwfn *p_hwfn);
261
262/**
263 * @brief ecore_iov_setup - setup sriov related resources
264 *
265 * @param p_hwfn
266 */
267void ecore_iov_setup(struct ecore_hwfn	*p_hwfn);
268
269/**
270 * @brief ecore_iov_free - free sriov related resources
271 *
272 * @param p_hwfn
273 */
274void ecore_iov_free(struct ecore_hwfn *p_hwfn);
275
276/**
277 * @brief free sriov related memory that was allocated during hw_prepare
278 *
279 * @param p_dev
280 */
281void ecore_iov_free_hw_info(struct ecore_dev *p_dev);
282
283/**
284 * @brief Mark structs of vfs that have been FLR-ed.
285 *
286 * @param p_hwfn
287 * @param disabled_vfs - bitmask of all VFs on path that were FLRed
288 *
289 * @return true iff one of the PF's vfs got FLRed. false otherwise.
290 */
291bool ecore_iov_mark_vf_flr(struct ecore_hwfn *p_hwfn,
292			  u32 *disabled_vfs);
293
294/**
295 * @brief Search extended TLVs in request/reply buffer.
296 *
297 * @param p_hwfn
298 * @param p_tlvs_list - Pointer to tlvs list
299 * @param req_type - Type of TLV
300 *
301 * @return pointer to tlv type if found, otherwise returns NULL.
302 */
303void *ecore_iov_search_list_tlvs(struct ecore_hwfn *p_hwfn,
304				 void *p_tlvs_list, u16 req_type);
305
306/**
307 * @brief ecore_iov_get_vf_info - return the database of a
308 *        specific VF
309 *
310 * @param p_hwfn
311 * @param relative_vf_id - relative id of the VF for which info
312 *			 is requested
313 * @param b_enabled_only - false iff want to access even if vf is disabled
314 *
315 * @return struct ecore_vf_info*
316 */
317struct ecore_vf_info *ecore_iov_get_vf_info(struct ecore_hwfn *p_hwfn,
318					    u16 relative_vf_id,
319					    bool b_enabled_only);
320#else
321static OSAL_INLINE enum _ecore_status_t ecore_iov_hw_info(struct ecore_hwfn OSAL_UNUSED *p_hwfn) {return ECORE_SUCCESS;}
322static OSAL_INLINE void *ecore_add_tlv(u8 OSAL_UNUSED **offset, OSAL_UNUSED u16 type, OSAL_UNUSED u16 length) {return OSAL_NULL;}
323static OSAL_INLINE void ecore_dp_tlv_list(struct ecore_hwfn OSAL_UNUSED *p_hwfn, void OSAL_UNUSED *tlvs_list) {}
324static OSAL_INLINE enum _ecore_status_t ecore_iov_alloc(struct ecore_hwfn OSAL_UNUSED *p_hwfn) {return ECORE_SUCCESS;}
325static OSAL_INLINE void ecore_iov_setup(struct ecore_hwfn OSAL_UNUSED *p_hwfn) {}
326static OSAL_INLINE void ecore_iov_free(struct ecore_hwfn OSAL_UNUSED *p_hwfn) {}
327static OSAL_INLINE void ecore_iov_free_hw_info(struct ecore_dev OSAL_UNUSED *p_dev) {}
328static OSAL_INLINE u32 ecore_crc32(u32 OSAL_UNUSED crc, u8 OSAL_UNUSED *ptr, u32 OSAL_UNUSED length) {return 0;}
329static OSAL_INLINE bool ecore_iov_mark_vf_flr(struct ecore_hwfn OSAL_UNUSED *p_hwfn, u32 OSAL_UNUSED *disabled_vfs) {return false;}
330static OSAL_INLINE void *ecore_iov_search_list_tlvs(struct ecore_hwfn OSAL_UNUSED *p_hwfn, void OSAL_UNUSED *p_tlvs_list, u16 OSAL_UNUSED req_type) {return OSAL_NULL;}
331static OSAL_INLINE struct ecore_vf_info *ecore_iov_get_vf_info(struct ecore_hwfn OSAL_UNUSED *p_hwfn, u16 OSAL_UNUSED relative_vf_id, bool OSAL_UNUSED b_enabled_only) {return OSAL_NULL;}
332
333#endif
334#endif /* __ECORE_SRIOV_H__ */
335