daf4e15ddb058ab4db835ad64d99f970c623df70
[dpdk.git] / drivers / net / mlx5 / windows / mlx5_flow_os.c
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         int 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 }