xref: /dpdk/drivers/net/mlx5/windows/mlx5_flow_os.c (revision e88bd4746737a1ca464b866d29f20ff5a739cd3f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020 Mellanox Technologies, Ltd
3  */
4 
5 #include "mlx5_flow_os.h"
6 #include "mlx5_win_ext.h"
7 
8 /**
9  * Verify the @p attributes will be correctly understood by the NIC and store
10  * them in the @p flow if everything is correct.
11  *
12  * @param[in] dev
13  *   Pointer to dev struct.
14  * @param[in] attributes
15  *   Pointer to flow attributes
16  * @param[in] external
17  *   This flow rule is created by request external to PMD.
18  * @param[out] error
19  *   Pointer to error structure.
20  *
21  * @return
22  *   - 0 on success and non root table (not a valid option for Windows yet).
23  *   - 1 on success and root table.
24  *   - a negative errno value otherwise and rte_errno is set.
25  */
26 int
27 mlx5_flow_os_validate_flow_attributes(struct rte_eth_dev *dev,
28 				      const struct rte_flow_attr *attributes,
29 				      bool external,
30 				      struct rte_flow_error *error)
31 {
32 	int ret = 1;
33 
34 	RTE_SET_USED(dev);
35 	RTE_SET_USED(external);
36 	if (attributes->group)
37 		return rte_flow_error_set(error, ENOTSUP,
38 					  RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
39 					  NULL,
40 					  "groups are not supported");
41 	if (attributes->priority)
42 		return rte_flow_error_set(error, ENOTSUP,
43 					  RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
44 					  NULL,
45 					  "priorities are not supported");
46 	if (attributes->transfer)
47 		return rte_flow_error_set(error, ENOTSUP,
48 					  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
49 					  NULL,
50 					  "transfer not supported");
51 	if (!(attributes->ingress))
52 		return rte_flow_error_set(error, ENOTSUP,
53 					  RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
54 					  NULL, "must specify ingress only");
55 	return ret;
56 }
57 
58 /**
59  * Create flow matcher in a flow table.
60  *
61  * @param[in] ctx
62  *   Pointer to relevant device context.
63  * @param[in] attr
64  *   Pointer to relevant attributes.
65  * @param[in] table
66  *   Pointer to table object.
67  * @param[out] matcher
68  *   Pointer to a valid flow matcher object on success, NULL otherwise.
69  *
70  * @return
71  *   0 on success, or errno on failure.
72  */
73 int
74 mlx5_flow_os_create_flow_matcher(void *ctx,
75 				 void *attr,
76 				 void *table,
77 				 void **matcher)
78 {
79 	struct mlx5dv_flow_matcher_attr *mattr;
80 
81 	RTE_SET_USED(table);
82 	*matcher = NULL;
83 	mattr = attr;
84 	if (mattr->type != IBV_FLOW_ATTR_NORMAL) {
85 		rte_errno = ENOTSUP;
86 		return -rte_errno;
87 	}
88 	struct mlx5_matcher *mlx5_matcher =
89 		mlx5_malloc(MLX5_MEM_ZERO,
90 		       sizeof(struct mlx5_matcher) +
91 		       MLX5_ST_SZ_BYTES(fte_match_param),
92 		       0, SOCKET_ID_ANY);
93 	if (!mlx5_matcher) {
94 		rte_errno = ENOMEM;
95 		return -rte_errno;
96 	}
97 	mlx5_matcher->ctx = ctx;
98 	memcpy(&mlx5_matcher->attr, attr, sizeof(mlx5_matcher->attr));
99 	memcpy(&mlx5_matcher->match_buf,
100 	       mattr->match_mask->match_buf,
101 	       MLX5_ST_SZ_BYTES(fte_match_param));
102 	*matcher = mlx5_matcher;
103 	return 0;
104 }
105 
106 /**
107  * Destroy flow matcher.
108  *
109  * @param[in] matcher
110  *   Pointer to matcher object to destroy.
111  *
112  * @return
113  *   0 on success, or the value of errno on failure.
114  */
115 int
116 mlx5_flow_os_destroy_flow_matcher(void *matcher)
117 {
118 	mlx5_free(matcher);
119 	return 0;
120 }
121 
122 /**
123  * Create flow action: dest_devx_tir
124  *
125  * @param[in] tir
126  *   Pointer to DevX tir object
127  * @param[out] action
128  *   Pointer to a valid action on success, NULL otherwise.
129  *
130  * @return
131  *   0 on success, or errno on failure.
132  */
133 int
134 mlx5_flow_os_create_flow_action_dest_devx_tir(struct mlx5_devx_obj *tir,
135 					      void **action)
136 {
137 	struct mlx5_action *mlx5_action =
138 		mlx5_malloc(MLX5_MEM_ZERO,
139 		       sizeof(struct mlx5_action),
140 		       0, SOCKET_ID_ANY);
141 
142 	if (!mlx5_action) {
143 		rte_errno = ENOMEM;
144 		return -rte_errno;
145 	}
146 	mlx5_action->type = MLX5_FLOW_CONTEXT_DEST_TYPE_TIR;
147 	mlx5_action->dest_tir.id = tir->id;
148 	*action = mlx5_action;
149 	return 0;
150 }
151 
152 /**
153  * Destroy flow action.
154  *
155  * @param[in] action
156  *   Pointer to action object to destroy.
157  *
158  * @return
159  *   0 on success, or the value of errno on failure.
160  */
161 int
162 mlx5_flow_os_destroy_flow_action(void *action)
163 {
164 	mlx5_free(action);
165 	return 0;
166 }
167 
168 /**
169  * Create flow rule.
170  *
171  * @param[in] matcher
172  *   Pointer to match mask structure.
173  * @param[in] match_value
174  *   Pointer to match value structure.
175  * @param[in] num_actions
176  *   Number of actions in flow rule.
177  * @param[in] actions
178  *   Pointer to array of flow rule actions.
179  * @param[out] flow
180  *   Pointer to a valid flow rule object on success, NULL otherwise.
181  *
182  * @return
183  *   0 on success, or errno on failure.
184  */
185 int
186 mlx5_flow_os_create_flow(void *matcher, void *match_value,
187 			 size_t num_actions,
188 			 void *actions[], void **flow)
189 {
190 	struct mlx5_action *action;
191 	size_t i;
192 	struct mlx5_matcher *mlx5_matcher = matcher;
193 	struct mlx5_flow_dv_match_params *mlx5_match_value = match_value;
194 	uint32_t in[MLX5_ST_SZ_DW(devx_fs_rule_add_in)] = {0};
195 	void *matcher_c = MLX5_ADDR_OF(devx_fs_rule_add_in, in,
196 				       match_criteria);
197 	void *matcher_v = MLX5_ADDR_OF(devx_fs_rule_add_in, in,
198 				       match_value);
199 
200 	MLX5_ASSERT(mlx5_matcher->ctx);
201 	memcpy(matcher_c, mlx5_matcher->match_buf,
202 	       mlx5_match_value->size);
203 	/* Use mlx5_match_value->size for match criteria */
204 	memcpy(matcher_v, mlx5_match_value->buf,
205 	       mlx5_match_value->size);
206 	for (i = 0; i < num_actions; i++) {
207 		action = actions[i];
208 		switch (action->type) {
209 		case MLX5_FLOW_CONTEXT_DEST_TYPE_TIR:
210 			MLX5_SET(devx_fs_rule_add_in, in,
211 				 dest.destination_type,
212 				 MLX5_FLOW_CONTEXT_DEST_TYPE_TIR);
213 			MLX5_SET(devx_fs_rule_add_in, in,
214 				 dest.destination_id,
215 				 action->dest_tir.id);
216 			break;
217 		default:
218 			break;
219 		}
220 		MLX5_SET(devx_fs_rule_add_in, in, match_criteria_enable,
221 			 MLX5_MATCH_OUTER_HEADERS);
222 	}
223 	*flow = mlx5_glue->devx_fs_rule_add(mlx5_matcher->ctx, in, sizeof(in));
224 	return (*flow) ? 0 : -1;
225 }
226 
227 /**
228  * Destroy flow rule.
229  *
230  * @param[in] drv_flow_ptr
231  *   Pointer to flow rule object.
232  *
233  * @return
234  *   0 on success, errno on failure.
235  */
236 int
237 mlx5_flow_os_destroy_flow(void *drv_flow_ptr)
238 {
239 	return mlx5_glue->devx_fs_rule_del(drv_flow_ptr);
240 }
241