1/* SPDX-License-Identifier: BSD-3-Clause */
2/*  Copyright (c) 2024, Intel Corporation
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 are met:
7 *
8 *   1. Redistributions of source code must retain the above copyright notice,
9 *      this list of conditions and the following disclaimer.
10 *
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 *   3. Neither the name of the Intel Corporation nor the names of its
16 *      contributors may be used to endorse or promote products derived from
17 *      this software without specific prior written permission.
18 *
19 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 *  POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/**
33 * @file ice_rdma.h
34 * @brief header file for RDMA client interface functions
35 *
36 * Contains definitions and function calls shared by the ice driver and the
37 * RDMA client interface driver.
38 *
39 * Since these definitions are shared between drivers it is important that any
40 * changes are considered carefully for backwards compatibility.
41 */
42#ifndef _ICE_RDMA_H_
43#define _ICE_RDMA_H_
44
45/*
46 * The RDMA client interface version is used to help determine
47 * incompatibilities between the interface definition shared between the main
48 * driver and the client driver.
49 *
50 * It will follows the semantic version guidelines, that is:
51 * Given the version number MAJOR.MINOR.PATCH, increment the:
52 *
53 * MAJOR version when you make incompatible changes,
54 * MINOR version when you add functionality in a backwards-compatible manner, and
55 * PATCH version when you make backwards-compatible bug fixes.
56 *
57 * Any change to this file, or one of the kobject interface files must come
58 * with an associated change in one of the MAJOR, MINOR, or PATCH versions,
59 * and care must be taken that backwards incompatible changes MUST increment
60 * the MAJOR version.
61 *
62 * Note: Until the MAJOR version is set to at least 1, the above semantic
63 * version guarantees may not hold, and this interface should not be
64 * considered stable.
65 */
66#define ICE_RDMA_MAJOR_VERSION 1
67#define ICE_RDMA_MINOR_VERSION 1
68#define ICE_RDMA_PATCH_VERSION 0
69
70/**
71 * @def ICE_RDMA_MAX_MSIX
72 * @brief Maximum number of MSI-X vectors that will be reserved
73 *
74 * Defines the maximum number of MSI-X vectors that an RDMA interface will
75 * have reserved in advance. Does not guarantee that many vectors have
76 * actually been enabled.
77 */
78#define ICE_RDMA_MAX_MSIX 64
79
80/**
81 * @struct ice_rdma_info
82 * @brief RDMA information from the client driver
83 *
84 * The RDMA client driver will fill in this structure and pass its contents
85 * back to the main driver using the ice_rdma_register function.
86 *
87 * It should fill the version in with the ICE_RDMA_* versions as defined in
88 * the ice_rdma.h header.
89 *
90 * Additionally it must provide a pointer to a kobject class which extends the
91 * ice_rdma_di_class with the operations defined in the rdma_if.m interface.
92 *
93 * If the version specified is not compatible, then the registration will
94 * of the RDMA driver will fail.
95 *
96 * @var ice_rdma_info::major_version
97 * 	describe major changes in the interface
98 * @var ice_rdma_info::minor_version
99 * 	describe changes and fixes with backward compatibility
100 * @var ice_rdma_info::patch_version
101 * 	changes without impact on compatibility or features
102 * @var ice_rdma_info::rdma_class
103 * 	kobject class
104 */
105struct ice_rdma_info {
106	uint16_t major_version;
107	uint16_t minor_version;
108	uint16_t patch_version;
109
110	kobj_class_t rdma_class;
111};
112
113#define ICE_RDMA_MAX_USER_PRIORITY	8
114#define ICE_RDMA_MAX_MSIX		64
115
116/* Declare the ice_rdma_di kobject class */
117DECLARE_CLASS(ice_rdma_di_class);
118
119/**
120 * @struct ice_rdma_msix_mapping
121 * @brief MSI-X mapping requested by the peer RDMA driver
122 *
123 * Defines a mapping for MSI-X vectors being requested by the peer RDMA driver
124 * for a given PF.
125 *
126 */
127struct ice_rdma_msix_mapping {
128	uint8_t itr_indx;
129	int aeq_vector;
130	int ceq_cnt;
131	int *ceq_vector;
132};
133
134/**
135 * @struct ice_rdma_msix
136 * @brief RDMA MSI-X vectors reserved for the peer RDMA driver
137 *
138 * Defines the segment of the MSI-X vectors for use by the RDMA driver. These
139 * are reserved by the PF when it initializes.
140 */
141struct ice_rdma_msix {
142	int base;
143	int count;
144};
145
146/**
147 * @struct ice_qos_info
148 * @brief QoS information to be shared with RDMA driver
149 */
150struct ice_qos_info {
151	uint64_t tc_ctx;
152	uint8_t rel_bw;
153	uint8_t prio_type;
154	uint8_t egress_virt_up;
155	uint8_t ingress_virt_up;
156};
157
158/**
159 * @struct ice_qos_app_priority_table
160 * @brief Application priority data
161 */
162struct ice_qos_app_priority_table {
163	uint16_t prot_id;
164	uint8_t priority;
165	uint8_t selector;
166};
167
168#define IEEE_8021QAZ_MAX_TCS  8
169#define ICE_TC_MAX_USER_PRIORITY 8
170#define ICE_QOS_MAX_APPS 32
171#define ICE_QOS_DSCP_NUM_VAL 64
172
173/**
174 * @struct ice_qos_params
175 * @brief Holds all necessary data for RDMA to work with DCB
176 *
177 * Struct to hold QoS info
178 * @var ice_qos_params::tc_info
179 *	traffic class information
180 * @var ice_qos_params::up2tc
181 *	mapping from user priority to traffic class
182 * @var ice_qos_params::vsi_relative_bw
183 *	bandwidth settings
184 * @var ice_qos_params::vsi_priority_type
185 *	priority type
186 * @var ice_qos_params::num_apps
187 *	app count
188 * @var ice_qos_params::pfc_mode
189 *	PFC mode
190 * @var ice_qos_params::dscp_map
191 *	dscp mapping
192 * @var ice_qos_params::apps
193 *	apps
194 * @var ice_qos_params::num_tc
195 *	number of traffic classes
196};
197 */
198struct ice_qos_params {
199	struct ice_qos_info tc_info[IEEE_8021QAZ_MAX_TCS];
200	uint8_t up2tc[ICE_TC_MAX_USER_PRIORITY];
201	uint8_t vsi_relative_bw;
202	uint8_t vsi_priority_type;
203	uint32_t num_apps;
204	uint8_t pfc_mode;
205	uint8_t dscp_map[ICE_QOS_DSCP_NUM_VAL];
206	struct ice_qos_app_priority_table apps[ICE_QOS_MAX_APPS];
207	uint8_t num_tc;
208};
209
210/**
211 * @struct ice_rdma_peer
212 * @brief RDMA driver information
213 *
214 * Shared structure used by the RDMA client driver when talking with the main
215 * device driver.
216 *
217 * Because the definition of this structure is shared between the two drivers,
218 * its ABI should be handled carefully.
219 *
220 * @var ice_rdma_peer::ifp
221 *	pointer to ifnet structure
222 * @var ice_rdma_peer::dev
223 *	device pointer
224 * @var ice_rdma_peer::pci_mem
225 *	information about PCI
226 * @var ice_rdma_peer::initial_qos_info
227 *	initial information on QoS
228 * @var ice_rdma_peer::msix
229 *	info about msix vectors
230 * @var ice_rdma_peer::mtu
231 *	initial mtu size
232 * @var ice_rdma_peer::pf_vsi_num
233 *	id of vsi
234 * @var ice_rdma_peer::pf_id
235 *	id of PF
236 */
237struct ice_rdma_peer {
238	/**
239	 * The KOBJ_FIELDS macro must come first, in order for it to be used
240	 * as a kobject.
241	 */
242	KOBJ_FIELDS;
243
244	struct ifnet *ifp;
245	device_t dev;
246	struct resource *pci_mem;
247	struct ice_qos_params initial_qos_info;
248	struct ice_rdma_msix msix;
249	uint16_t mtu;
250	uint16_t pf_vsi_num;
251	uint8_t pf_id;
252};
253
254/**
255 * @enum ice_res_type
256 * @brief enum for type of resource registration
257 *
258 * enum for type of resource registration.
259 * created for plausible compatibility with IDC
260 */
261enum ice_res_type {
262	ICE_INVAL_RES = 0x0,
263	ICE_RDMA_QSET_ALLOC = 0x8,
264	ICE_RDMA_QSET_FREE = 0x18,
265};
266
267/**
268 * @struct ice_rdma_qset_params
269 * @brief struct to hold per RDMA Qset info
270 *
271 * @var ice_rdma_qset_params::teid
272 *	qset teid
273 * @var ice_rdma_qset_params::qs_handle
274 *	qset from rdma driver
275 * @var ice_rdma_qset_params::vsi_id
276 *	vsi index
277 * @var ice_rdma_qset_params::tc
278 *	traffic class to which qset should belong to
279 * @var ice_rdma_qset_params::reserved
280 *	for future use
281 */
282struct ice_rdma_qset_params {
283	uint32_t teid;
284	uint16_t qs_handle;
285	uint16_t vsi_id;
286	uint8_t tc;
287	uint8_t reserved[3];
288};
289
290#define ICE_MAX_TXQ_PER_TXQG 128
291/**
292 * @struct ice_rdma_qset_update
293 * @brief struct used to register and unregister qsets for RDMA driver
294 *
295 * @var ice_rdma_qset_update::res_type
296 *	ALLOC or FREE
297 * @var ice_rdma_qset_update::cnt_req
298 *	how many qsets are requested
299 * @var ice_rdma_qset_update::res_allocated
300 *	how many qsets are allocated
301 * @var ice_rdma_qset_update::qsets
302 *	rdma qset info
303 */
304struct ice_rdma_qset_update {
305	enum ice_res_type res_type;
306	uint16_t cnt_req;
307	uint16_t res_allocated;
308	uint32_t res_handle;
309	struct ice_rdma_qset_params qsets;
310};
311
312/**
313 * @enum ice_rdma_event_type
314 * @brief enum for type of event from base driver
315 */
316enum ice_rdma_event_type {
317	ICE_RDMA_EVENT_NONE = 0,
318	ICE_RDMA_EVENT_LINK_CHANGE,
319	ICE_RDMA_EVENT_MTU_CHANGE,
320	ICE_RDMA_EVENT_TC_CHANGE,
321	ICE_RDMA_EVENT_API_CHANGE,
322	ICE_RDMA_EVENT_CRIT_ERR,
323	ICE_RDMA_EVENT_RESET,
324	ICE_RDMA_EVENT_QSET_REGISTER,
325	ICE_RDMA_EVENT_VSI_FILTER_UPDATE,
326	ICE_RDMA_EVENT_LAST
327};
328
329/**
330 * @struct ice_rdma_event
331 * @brief struct for event information to pass to RDMA driver
332 *
333 * @var ice_rdma_event::type
334 *	event type
335 */
336struct ice_rdma_event {
337	enum ice_rdma_event_type type;
338	union {
339		/* link change event */
340		struct {
341			int linkstate;
342			uint64_t baudrate;
343		};
344		/* MTU change event */
345		int mtu;
346		/*
347		 * TC/QoS/DCB change event
348		 * prep: if true, this is a pre-event, post-event otherwise
349		 */
350		struct {
351			struct ice_qos_params port_qos;
352			bool prep;
353		};
354		/*
355		 * CRIT_ERR event
356		 */
357		uint32_t oicr_reg;
358	};
359};
360
361/**
362 * @struct ice_rdma_request
363 * @brief struct with data for a request from the RDMA driver
364 *
365 * @var ice_rdma_request::type
366 *	event type
367 */
368struct ice_rdma_request {
369	enum ice_rdma_event_type type;
370	union {
371		struct {
372			struct ice_rdma_qset_update res;
373		};
374		struct {
375			bool enable_filter;
376		};
377	};
378};
379
380int ice_rdma_register(struct ice_rdma_info *info);
381int ice_rdma_unregister(void);
382
383#endif
384