File: flow_api.h

package info (click to toggle)
dpdk 25.11-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 127,892 kB
  • sloc: ansic: 2,358,479; python: 16,426; sh: 4,474; makefile: 1,713; awk: 70
file content (232 lines) | stat: -rw-r--r-- 8,731 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright(c) 2023 Napatech A/S
 */

#ifndef _FLOW_API_H_
#define _FLOW_API_H_

#include <rte_spinlock.h>

#include "ntlog.h"

#include "flow_api_engine.h"
#include "hw_mod_backend.h"
#include "stream_binary_flow_api.h"

/*
 * Flow NIC and Eth port device management
 */

struct hw_mod_resource_s {
	uint8_t *alloc_bm;      /* allocation bitmap */
	uint32_t *ref;  /* reference counter for each resource element */
	uint32_t resource_count;/* number of total available entries */
};

/*
 * Device Management API
 */
/**
 * A structure used to configure the Receive Side Scaling (RSS) feature
 * of an Ethernet port.
 */
struct nt_eth_rss_conf {
	/**
	 * In rte_eth_dev_rss_hash_conf_get(), the *rss_key_len* should be
	 * greater than or equal to the *hash_key_size* which get from
	 * rte_eth_dev_info_get() API. And the *rss_key* should contain at least
	 * *hash_key_size* bytes. If not meet these requirements, the query
	 * result is unreliable even if the operation returns success.
	 *
	 * In rte_eth_dev_rss_hash_update() or rte_eth_dev_configure(), if
	 * *rss_key* is not NULL, the *rss_key_len* indicates the length of the
	 * *rss_key* in bytes and it should be equal to *hash_key_size*.
	 * If *rss_key* is NULL, drivers are free to use a random or a default key.
	 */
	uint8_t rss_key[MAX_RSS_KEY_LEN];
	/**
	 * Indicates the type of packets or the specific part of packets to
	 * which RSS hashing is to be applied.
	 */
	uint64_t rss_hf;
	/**
	 * Hash algorithm.
	 */
	enum rte_eth_hash_function algorithm;
};

int nthw_sprint_rss_mask(char *str, uint16_t str_len, const char *prefix, uint64_t hash_mask);

struct flow_eth_dev {
	/* NIC that owns this port device */
	struct flow_nic_dev *ndev;
	/* NIC port id */
	uint8_t port;
	/* App assigned port_id - may be DPDK port_id */
	uint32_t port_id;

	/* 0th for exception */
	struct flow_queue_id_s rx_queue[FLOW_MAX_QUEUES + 1];

	/* VSWITCH has exceptions sent on queue 0 per design */
	int num_queues;

	/* QSL_HSH index if RSS needed QSL v6+ */
	int rss_target_id;

	/* The size of buffer for aged out flow list */
	uint32_t nb_aging_objects;

	struct flow_eth_dev *next;
};

/* registered NIC backends */
struct flow_nic_dev {
	uint8_t adapter_no;     /* physical adapter no in the host system */
	uint16_t ports; /* number of in-ports addressable on this NIC */
	/* flow profile this NIC is initially prepared for */
	enum flow_eth_dev_profile flow_profile;
	int flow_mgnt_prepared;

	struct hw_mod_resource_s res[RES_COUNT];/* raw NIC resource allocation table */
	void *km_res_handle;
	void *kcc_res_handle;

	void *flm_mtr_handle;
	void *group_handle;
	void *hw_db_handle;
	void *id_table_handle;

	uint32_t flow_unique_id_counter;
	/* linked list of all flows created on this NIC */
	struct flow_handle *flow_base;
	/* linked list of all FLM flows created on this NIC */
	struct flow_handle *flow_base_flm;
	rte_spinlock_t flow_mtx;

	/* NIC backend API */
	struct flow_api_backend_s be;
	/* linked list of created eth-port devices on this NIC */
	struct flow_eth_dev *eth_base;
	rte_spinlock_t mtx;

	/* RSS hashing configuration */
	struct nt_eth_rss_conf rss_conf;
	/* next NIC linked list */
	struct flow_nic_dev *next;
};

enum flow_nic_err_msg_e {
	ERR_SUCCESS = 0,
	ERR_FAILED = 1,
	ERR_MEMORY = 2,
	ERR_OUTPUT_TOO_MANY = 3,
	ERR_RSS_TOO_MANY_QUEUES = 4,
	ERR_VLAN_TYPE_NOT_SUPPORTED = 5,
	ERR_VXLAN_HEADER_NOT_ACCEPTED = 6,
	ERR_VXLAN_POP_INVALID_RECIRC_PORT = 7,
	ERR_VXLAN_POP_FAILED_CREATING_VTEP = 8,
	ERR_MATCH_VLAN_TOO_MANY = 9,
	ERR_MATCH_INVALID_IPV6_HDR = 10,
	ERR_MATCH_TOO_MANY_TUNNEL_PORTS = 11,
	ERR_MATCH_INVALID_OR_UNSUPPORTED_ELEM = 12,
	ERR_MATCH_FAILED_BY_HW_LIMITS = 13,
	ERR_MATCH_RESOURCE_EXHAUSTION = 14,
	ERR_MATCH_FAILED_TOO_COMPLEX = 15,
	ERR_ACTION_REPLICATION_FAILED = 16,
	ERR_ACTION_OUTPUT_RESOURCE_EXHAUSTION = 17,
	ERR_ACTION_TUNNEL_HEADER_PUSH_OUTPUT_LIMIT = 18,
	ERR_ACTION_INLINE_MOD_RESOURCE_EXHAUSTION = 19,
	ERR_ACTION_RETRANSMIT_RESOURCE_EXHAUSTION = 20,
	ERR_ACTION_FLOW_COUNTER_EXHAUSTION = 21,
	ERR_ACTION_INTERNAL_RESOURCE_EXHAUSTION = 22,
	ERR_INTERNAL_QSL_COMPARE_FAILED = 23,
	ERR_INTERNAL_CAT_FUNC_REUSE_FAILED = 24,
	ERR_MATCH_ENTROPHY_FAILED = 25,
	ERR_MATCH_CAM_EXHAUSTED = 26,
	ERR_INTERNAL_VIRTUAL_PORT_CREATION_FAILED = 27,
	ERR_ACTION_UNSUPPORTED = 28,
	ERR_REMOVE_FLOW_FAILED = 29,
	ERR_ACTION_NO_OUTPUT_DEFINED_USE_DEFAULT = 30,
	ERR_ACTION_NO_OUTPUT_QUEUE_FOUND = 31,
	ERR_MATCH_UNSUPPORTED_ETHER_TYPE = 32,
	ERR_OUTPUT_INVALID = 33,
	ERR_MATCH_PARTIAL_OFFLOAD_NOT_SUPPORTED = 34,
	ERR_MATCH_CAT_CAM_EXHAUSTED = 35,
	ERR_MATCH_KCC_KEY_CLASH = 36,
	ERR_MATCH_CAT_CAM_FAILED = 37,
	ERR_PARTIAL_FLOW_MARK_TOO_BIG = 38,
	ERR_FLOW_PRIORITY_VALUE_INVALID = 39,
	ERR_ACTION_MULTIPLE_PORT_ID_UNSUPPORTED = 40,
	ERR_RSS_TOO_LONG_KEY = 41,
	ERR_ACTION_AGE_UNSUPPORTED_GROUP_0 = 42,
	ERR_MSG_NO_MSG = 43,
	ERR_MSG_END
};

void nthw_flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error *error);

/*
 * Resources
 */

extern const char *nthw_dbg_res_descr[];

#define flow_nic_set_bit(arr, x)                                                                  \
	do {                                                                                      \
		uint8_t *_temp_arr = (arr);                                                       \
		size_t _temp_x = (x);                                                             \
		_temp_arr[_temp_x / 8] =                                                          \
			(uint8_t)(_temp_arr[_temp_x / 8] | (uint8_t)(1 << (_temp_x % 8)));        \
	} while (0)

#define flow_nic_unset_bit(arr, x)                                                                \
	do {                                                                                      \
		size_t _temp_x = (x);                                                             \
		arr[_temp_x / 8] &= (uint8_t)(~(1 << (_temp_x % 8)));                             \
	} while (0)

#define flow_nic_is_bit_set(arr, x)                                                               \
	({                                                                                        \
		size_t _temp_x = (x);                                                             \
		(arr[_temp_x / 8] & (uint8_t)(1 << (_temp_x % 8)));                               \
	})

#define flow_nic_mark_resource_used(_ndev, res_type, index)                                       \
	do {                                                                                      \
		struct flow_nic_dev *_temp_ndev = (_ndev);                                        \
		typeof(res_type) _temp_res_type = (res_type);                                     \
		size_t _temp_index = (index);                                                     \
		NT_LOG(DBG, FILTER, "mark resource used: %s idx %zu",                             \
		       nthw_dbg_res_descr[_temp_res_type], _temp_index);                          \
		RTE_ASSERT(flow_nic_is_bit_set(_temp_ndev->res[_temp_res_type].alloc_bm,          \
					   _temp_index) == 0);                                    \
		flow_nic_set_bit(_temp_ndev->res[_temp_res_type].alloc_bm, _temp_index);          \
	} while (0)

#define flow_nic_mark_resource_unused(_ndev, res_type, index)                                     \
	do {                                                                                      \
		typeof(res_type) _temp_res_type = (res_type);                                 \
		size_t _temp_index = (index);                                                     \
		NT_LOG(DBG, FILTER, "mark resource unused: %s idx %zu",                         \
		       nthw_dbg_res_descr[_temp_res_type], _temp_index);                          \
		flow_nic_unset_bit((_ndev)->res[_temp_res_type].alloc_bm, _temp_index);           \
	} while (0)

#define flow_nic_is_resource_used(_ndev, res_type, index)                                         \
	(!!flow_nic_is_bit_set((_ndev)->res[res_type].alloc_bm, index))

int nthw_flow_nic_alloc_resource(struct flow_nic_dev *ndev, enum res_type_e res_type,
	uint32_t alignment);

int nthw_flow_nic_alloc_resource_config(struct flow_nic_dev *ndev, enum res_type_e res_type,
	unsigned int num, uint32_t alignment);
void nthw_flow_nic_free_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int idx);

int nthw_flow_nic_ref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index);
int nthw_flow_nic_deref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index);

int nthw_flow_get_flm_stats(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size);
int nthw_flow_get_ifr_stats(struct flow_nic_dev *ndev, uint64_t *data, uint8_t port_count);

#endif