Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2017 Cavium Inc.
3 : : * All rights reserved.
4 : : * www.cavium.com
5 : : */
6 : :
7 : : #include <rte_udp.h>
8 : : #include <rte_tcp.h>
9 : : #include <rte_sctp.h>
10 : : #include <rte_errno.h>
11 : : #include <rte_flow_driver.h>
12 : :
13 : : #include "qede_ethdev.h"
14 : :
15 : : /* VXLAN tunnel classification mapping */
16 : : const struct _qede_udp_tunn_types {
17 : : uint16_t rte_filter_type;
18 : : enum ecore_filter_ucast_type qede_type;
19 : : enum ecore_tunn_clss qede_tunn_clss;
20 : : const char *string;
21 : : } qede_tunn_types[] = {
22 : : {
23 : : RTE_ETH_TUNNEL_FILTER_OMAC,
24 : : ECORE_FILTER_MAC,
25 : : ECORE_TUNN_CLSS_MAC_VLAN,
26 : : "outer-mac"
27 : : },
28 : : {
29 : : RTE_ETH_TUNNEL_FILTER_TENID,
30 : : ECORE_FILTER_VNI,
31 : : ECORE_TUNN_CLSS_MAC_VNI,
32 : : "vni"
33 : : },
34 : : {
35 : : RTE_ETH_TUNNEL_FILTER_IMAC,
36 : : ECORE_FILTER_INNER_MAC,
37 : : ECORE_TUNN_CLSS_INNER_MAC_VLAN,
38 : : "inner-mac"
39 : : },
40 : : {
41 : : RTE_ETH_TUNNEL_FILTER_IVLAN,
42 : : ECORE_FILTER_INNER_VLAN,
43 : : ECORE_TUNN_CLSS_INNER_MAC_VLAN,
44 : : "inner-vlan"
45 : : },
46 : : {
47 : : RTE_ETH_TUNNEL_FILTER_OMAC | RTE_ETH_TUNNEL_FILTER_TENID,
48 : : ECORE_FILTER_MAC_VNI_PAIR,
49 : : ECORE_TUNN_CLSS_MAC_VNI,
50 : : "outer-mac and vni"
51 : : },
52 : : {
53 : : RTE_ETH_TUNNEL_FILTER_OMAC | RTE_ETH_TUNNEL_FILTER_IMAC,
54 : : ECORE_FILTER_UNUSED,
55 : : MAX_ECORE_TUNN_CLSS,
56 : : "outer-mac and inner-mac"
57 : : },
58 : : {
59 : : RTE_ETH_TUNNEL_FILTER_OMAC | RTE_ETH_TUNNEL_FILTER_IVLAN,
60 : : ECORE_FILTER_UNUSED,
61 : : MAX_ECORE_TUNN_CLSS,
62 : : "outer-mac and inner-vlan"
63 : : },
64 : : {
65 : : RTE_ETH_TUNNEL_FILTER_TENID | RTE_ETH_TUNNEL_FILTER_IMAC,
66 : : ECORE_FILTER_INNER_MAC_VNI_PAIR,
67 : : ECORE_TUNN_CLSS_INNER_MAC_VNI,
68 : : "vni and inner-mac",
69 : : },
70 : : {
71 : : RTE_ETH_TUNNEL_FILTER_TENID | RTE_ETH_TUNNEL_FILTER_IVLAN,
72 : : ECORE_FILTER_UNUSED,
73 : : MAX_ECORE_TUNN_CLSS,
74 : : "vni and inner-vlan",
75 : : },
76 : : {
77 : : RTE_ETH_TUNNEL_FILTER_IMAC | RTE_ETH_TUNNEL_FILTER_IVLAN,
78 : : ECORE_FILTER_INNER_PAIR,
79 : : ECORE_TUNN_CLSS_INNER_MAC_VLAN,
80 : : "inner-mac and inner-vlan",
81 : : },
82 : : {
83 : : RTE_ETH_TUNNEL_FILTER_OIP,
84 : : ECORE_FILTER_UNUSED,
85 : : MAX_ECORE_TUNN_CLSS,
86 : : "outer-IP"
87 : : },
88 : : {
89 : : RTE_ETH_TUNNEL_FILTER_IIP,
90 : : ECORE_FILTER_UNUSED,
91 : : MAX_ECORE_TUNN_CLSS,
92 : : "inner-IP"
93 : : },
94 : : {
95 : : RTE_ETH_TUNNEL_FILTER_IMAC_IVLAN,
96 : : ECORE_FILTER_UNUSED,
97 : : MAX_ECORE_TUNN_CLSS,
98 : : "IMAC_IVLAN"
99 : : },
100 : : {
101 : : RTE_ETH_TUNNEL_FILTER_IMAC_IVLAN_TENID,
102 : : ECORE_FILTER_UNUSED,
103 : : MAX_ECORE_TUNN_CLSS,
104 : : "IMAC_IVLAN_TENID"
105 : : },
106 : : {
107 : : RTE_ETH_TUNNEL_FILTER_IMAC_TENID,
108 : : ECORE_FILTER_UNUSED,
109 : : MAX_ECORE_TUNN_CLSS,
110 : : "IMAC_TENID"
111 : : },
112 : : {
113 : : RTE_ETH_TUNNEL_FILTER_OMAC_TENID_IMAC,
114 : : ECORE_FILTER_UNUSED,
115 : : MAX_ECORE_TUNN_CLSS,
116 : : "OMAC_TENID_IMAC"
117 : : },
118 : : };
119 : :
120 : : #define IP_VERSION (0x40)
121 : : #define IP_HDRLEN (0x5)
122 : : #define QEDE_FDIR_IP_DEFAULT_VERSION_IHL (IP_VERSION | IP_HDRLEN)
123 : : #define QEDE_FDIR_TCP_DEFAULT_DATAOFF (0x50)
124 : : #define QEDE_FDIR_IPV4_DEF_TTL (64)
125 : : #define QEDE_FDIR_IPV6_DEFAULT_VTC_FLOW (0x60000000)
126 : : /* Sum of length of header types of L2, L3, L4.
127 : : * L2 : ether_hdr + vlan_hdr + vxlan_hdr
128 : : * L3 : ipv6_hdr
129 : : * L4 : tcp_hdr
130 : : */
131 : : #define QEDE_MAX_FDIR_PKT_LEN (86)
132 : :
133 : : static uint16_t
134 : : qede_arfs_construct_pkt(struct rte_eth_dev *eth_dev,
135 : : struct qede_arfs_entry *arfs,
136 : : void *buff,
137 : : struct ecore_arfs_config_params *params);
138 : :
139 : : /* Note: Flowdir support is only partial.
140 : : * For ex: drop_queue, FDIR masks, flex_conf are not supported.
141 : : * Parameters like pballoc/status fields are irrelevant here.
142 : : */
143 : 0 : int qede_check_fdir_support(struct rte_eth_dev *eth_dev)
144 : : {
145 : 0 : struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
146 : : struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
147 : :
148 : 0 : qdev->arfs_info.arfs.mode = ECORE_FILTER_CONFIG_MODE_DISABLE;
149 : 0 : DP_INFO(edev, "flowdir is disabled\n");
150 : :
151 : 0 : return 0;
152 : : }
153 : :
154 : 0 : void qede_fdir_dealloc_resc(struct rte_eth_dev *eth_dev)
155 : : {
156 : 0 : struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
157 : : struct qede_arfs_entry *tmp = NULL;
158 : :
159 [ # # ]: 0 : SLIST_FOREACH(tmp, &qdev->arfs_info.arfs_list_head, list) {
160 : : if (tmp) {
161 [ # # ]: 0 : if (tmp->mz)
162 : 0 : rte_memzone_free(tmp->mz);
163 [ # # # # ]: 0 : SLIST_REMOVE(&qdev->arfs_info.arfs_list_head, tmp,
164 : : qede_arfs_entry, list);
165 : 0 : rte_free(tmp);
166 : : }
167 : : }
168 : 0 : }
169 : :
170 : : static int
171 : 0 : qede_config_arfs_filter(struct rte_eth_dev *eth_dev,
172 : : struct qede_arfs_entry *arfs,
173 : : bool add)
174 : : {
175 : 0 : struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
176 : : struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
177 : : struct ecore_ntuple_filter_params params;
178 : 0 : char mz_name[RTE_MEMZONE_NAMESIZE] = {0};
179 : : struct qede_arfs_entry *tmp = NULL;
180 : : const struct rte_memzone *mz;
181 : : struct ecore_hwfn *p_hwfn;
182 : : enum _ecore_status_t rc;
183 : : uint16_t pkt_len;
184 : : void *pkt;
185 : :
186 [ # # ]: 0 : if (add) {
187 [ # # ]: 0 : if (qdev->arfs_info.filter_count == QEDE_RFS_MAX_FLTR - 1) {
188 : 0 : DP_ERR(edev, "Reached max flowdir filter limit\n");
189 : 0 : return -EINVAL;
190 : : }
191 : : }
192 : :
193 : : /* soft_id could have been used as memzone string, but soft_id is
194 : : * not currently used so it has no significance.
195 : : */
196 : : snprintf(mz_name, sizeof(mz_name), "%lx",
197 : : (unsigned long)rte_get_timer_cycles());
198 : 0 : mz = rte_memzone_reserve_aligned(mz_name, QEDE_MAX_FDIR_PKT_LEN,
199 : : SOCKET_ID_ANY, 0, RTE_CACHE_LINE_SIZE);
200 [ # # ]: 0 : if (!mz) {
201 : 0 : DP_ERR(edev, "Failed to allocate memzone for fdir, err = %s\n",
202 : : rte_strerror(rte_errno));
203 : 0 : return -rte_errno;
204 : : }
205 : :
206 : 0 : pkt = mz->addr;
207 : : memset(pkt, 0, QEDE_MAX_FDIR_PKT_LEN);
208 : 0 : pkt_len = qede_arfs_construct_pkt(eth_dev, arfs, pkt,
209 : : &qdev->arfs_info.arfs);
210 [ # # ]: 0 : if (pkt_len == 0) {
211 : : rc = -EINVAL;
212 : 0 : goto err1;
213 : : }
214 : :
215 : 0 : DP_INFO(edev, "pkt_len = %u memzone = %s\n", pkt_len, mz_name);
216 [ # # ]: 0 : if (add) {
217 [ # # ]: 0 : SLIST_FOREACH(tmp, &qdev->arfs_info.arfs_list_head, list) {
218 [ # # ]: 0 : if (memcmp(tmp->mz->addr, pkt, pkt_len) == 0) {
219 : 0 : DP_INFO(edev, "flowdir filter exist\n");
220 : : rc = -EEXIST;
221 : 0 : goto err1;
222 : : }
223 : : }
224 : : } else {
225 [ # # ]: 0 : SLIST_FOREACH(tmp, &qdev->arfs_info.arfs_list_head, list) {
226 [ # # ]: 0 : if (memcmp(tmp->mz->addr, pkt, pkt_len) == 0)
227 : : break;
228 : : }
229 [ # # ]: 0 : if (!tmp) {
230 : 0 : DP_ERR(edev, "flowdir filter does not exist\n");
231 : : rc = -EEXIST;
232 : 0 : goto err1;
233 : : }
234 : : }
235 : 0 : p_hwfn = ECORE_LEADING_HWFN(edev);
236 [ # # ]: 0 : if (add) {
237 [ # # ]: 0 : if (qdev->arfs_info.arfs.mode ==
238 : : ECORE_FILTER_CONFIG_MODE_DISABLE) {
239 : 0 : qdev->arfs_info.arfs.mode =
240 : : ECORE_FILTER_CONFIG_MODE_5_TUPLE;
241 : 0 : DP_INFO(edev, "Force enable flowdir in perfect mode\n");
242 : : }
243 : : /* Enable ARFS searcher with updated flow_types */
244 : 0 : ecore_arfs_mode_configure(p_hwfn, p_hwfn->p_arfs_ptt,
245 : : &qdev->arfs_info.arfs);
246 : : }
247 : :
248 : : memset(¶ms, 0, sizeof(params));
249 : 0 : params.addr = (dma_addr_t)mz->iova;
250 : 0 : params.length = pkt_len;
251 : 0 : params.qid = arfs->rx_queue;
252 : : params.vport_id = 0;
253 : 0 : params.b_is_add = add;
254 : 0 : params.b_is_drop = arfs->is_drop;
255 : :
256 : : /* configure filter with ECORE_SPQ_MODE_EBLOCK */
257 : 0 : rc = ecore_configure_rfs_ntuple_filter(p_hwfn, NULL,
258 : : ¶ms);
259 [ # # ]: 0 : if (rc == ECORE_SUCCESS) {
260 [ # # ]: 0 : if (add) {
261 : 0 : arfs->pkt_len = pkt_len;
262 : 0 : arfs->mz = mz;
263 : 0 : SLIST_INSERT_HEAD(&qdev->arfs_info.arfs_list_head,
264 : : arfs, list);
265 : 0 : qdev->arfs_info.filter_count++;
266 : 0 : DP_INFO(edev, "flowdir filter added, count = %d\n",
267 : : qdev->arfs_info.filter_count);
268 : : } else {
269 : 0 : rte_memzone_free(tmp->mz);
270 [ # # # # ]: 0 : SLIST_REMOVE(&qdev->arfs_info.arfs_list_head, tmp,
271 : : qede_arfs_entry, list);
272 : 0 : rte_free(tmp); /* the node deleted */
273 : 0 : rte_memzone_free(mz); /* temp node allocated */
274 : 0 : qdev->arfs_info.filter_count--;
275 : 0 : DP_INFO(edev, "Fdir filter deleted, count = %d\n",
276 : : qdev->arfs_info.filter_count);
277 : : }
278 : : } else {
279 : 0 : DP_ERR(edev, "flowdir filter failed, rc=%d filter_count=%d\n",
280 : : rc, qdev->arfs_info.filter_count);
281 : : }
282 : :
283 : : /* Disable ARFS searcher if there are no more filters */
284 [ # # ]: 0 : if (qdev->arfs_info.filter_count == 0) {
285 : : memset(&qdev->arfs_info.arfs, 0,
286 : : sizeof(struct ecore_arfs_config_params));
287 : 0 : DP_INFO(edev, "Disabling flowdir\n");
288 : 0 : qdev->arfs_info.arfs.mode = ECORE_FILTER_CONFIG_MODE_DISABLE;
289 : 0 : ecore_arfs_mode_configure(p_hwfn, p_hwfn->p_arfs_ptt,
290 : : &qdev->arfs_info.arfs);
291 : : }
292 : : return 0;
293 : :
294 : 0 : err1:
295 : 0 : rte_memzone_free(mz);
296 : 0 : return rc;
297 : : }
298 : :
299 : : /* Fills the L3/L4 headers and returns the actual length of flowdir packet */
300 : : static uint16_t
301 : 0 : qede_arfs_construct_pkt(struct rte_eth_dev *eth_dev,
302 : : struct qede_arfs_entry *arfs,
303 : : void *buff,
304 : : struct ecore_arfs_config_params *params)
305 : :
306 : : {
307 : 0 : struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
308 : : struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
309 : : uint16_t *ether_type;
310 : : uint8_t *raw_pkt;
311 : : struct rte_ipv4_hdr *ip;
312 : : struct rte_ipv6_hdr *ip6;
313 : : struct rte_udp_hdr *udp;
314 : : struct rte_tcp_hdr *tcp;
315 : : uint16_t len;
316 : :
317 : : raw_pkt = (uint8_t *)buff;
318 : :
319 : : len = 2 * sizeof(struct rte_ether_addr);
320 : : raw_pkt += 2 * sizeof(struct rte_ether_addr);
321 : : ether_type = (uint16_t *)raw_pkt;
322 : : raw_pkt += sizeof(uint16_t);
323 : : len += sizeof(uint16_t);
324 : :
325 [ # # ]: 0 : *ether_type = rte_cpu_to_be_16(arfs->tuple.eth_proto);
326 [ # # # ]: 0 : switch (arfs->tuple.eth_proto) {
327 : 0 : case RTE_ETHER_TYPE_IPV4:
328 : : ip = (struct rte_ipv4_hdr *)raw_pkt;
329 : 0 : ip->version_ihl = QEDE_FDIR_IP_DEFAULT_VERSION_IHL;
330 : 0 : ip->total_length = sizeof(struct rte_ipv4_hdr);
331 : 0 : ip->next_proto_id = arfs->tuple.ip_proto;
332 : 0 : ip->time_to_live = QEDE_FDIR_IPV4_DEF_TTL;
333 : 0 : ip->dst_addr = arfs->tuple.dst_ipv4;
334 : 0 : ip->src_addr = arfs->tuple.src_ipv4;
335 : : len += sizeof(struct rte_ipv4_hdr);
336 : 0 : params->ipv4 = true;
337 : :
338 : : raw_pkt = (uint8_t *)buff;
339 : : /* UDP */
340 [ # # ]: 0 : if (arfs->tuple.ip_proto == IPPROTO_UDP) {
341 : : udp = (struct rte_udp_hdr *)(raw_pkt + len);
342 : 0 : udp->dst_port = arfs->tuple.dst_port;
343 : 0 : udp->src_port = arfs->tuple.src_port;
344 : 0 : udp->dgram_len = sizeof(struct rte_udp_hdr);
345 : : len += sizeof(struct rte_udp_hdr);
346 : : /* adjust ip total_length */
347 : 0 : ip->total_length += sizeof(struct rte_udp_hdr);
348 : 0 : params->udp = true;
349 : : } else { /* TCP */
350 : : tcp = (struct rte_tcp_hdr *)(raw_pkt + len);
351 : 0 : tcp->src_port = arfs->tuple.src_port;
352 : 0 : tcp->dst_port = arfs->tuple.dst_port;
353 : 0 : tcp->data_off = QEDE_FDIR_TCP_DEFAULT_DATAOFF;
354 : : len += sizeof(struct rte_tcp_hdr);
355 : : /* adjust ip total_length */
356 : 0 : ip->total_length += sizeof(struct rte_tcp_hdr);
357 : 0 : params->tcp = true;
358 : : }
359 : : break;
360 : 0 : case RTE_ETHER_TYPE_IPV6:
361 : : ip6 = (struct rte_ipv6_hdr *)raw_pkt;
362 : 0 : ip6->proto = arfs->tuple.ip_proto;
363 : 0 : ip6->vtc_flow =
364 : : rte_cpu_to_be_32(QEDE_FDIR_IPV6_DEFAULT_VTC_FLOW);
365 : :
366 [ # # ]: 0 : memcpy(&ip6->src_addr, arfs->tuple.src_ipv6, IPV6_ADDR_LEN);
367 : 0 : memcpy(&ip6->dst_addr, arfs->tuple.dst_ipv6, IPV6_ADDR_LEN);
368 : : len += sizeof(struct rte_ipv6_hdr);
369 : 0 : params->ipv6 = true;
370 : :
371 : : raw_pkt = (uint8_t *)buff;
372 : : /* UDP */
373 [ # # ]: 0 : if (arfs->tuple.ip_proto == IPPROTO_UDP) {
374 : : udp = (struct rte_udp_hdr *)(raw_pkt + len);
375 : 0 : udp->src_port = arfs->tuple.src_port;
376 : 0 : udp->dst_port = arfs->tuple.dst_port;
377 : : len += sizeof(struct rte_udp_hdr);
378 : 0 : params->udp = true;
379 : : } else { /* TCP */
380 : : tcp = (struct rte_tcp_hdr *)(raw_pkt + len);
381 : 0 : tcp->src_port = arfs->tuple.src_port;
382 : 0 : tcp->dst_port = arfs->tuple.dst_port;
383 : 0 : tcp->data_off = QEDE_FDIR_TCP_DEFAULT_DATAOFF;
384 : : len += sizeof(struct rte_tcp_hdr);
385 : 0 : params->tcp = true;
386 : : }
387 : : break;
388 : 0 : default:
389 : 0 : DP_ERR(edev, "Unsupported eth_proto %u\n",
390 : : arfs->tuple.eth_proto);
391 : 0 : return 0;
392 : : }
393 : :
394 : : return len;
395 : : }
396 : :
397 : : static int
398 : 0 : qede_tunnel_update(struct qede_dev *qdev,
399 : : struct ecore_tunnel_info *tunn_info)
400 : : {
401 : : struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
402 : : enum _ecore_status_t rc = ECORE_INVAL;
403 : : struct ecore_hwfn *p_hwfn;
404 : : struct ecore_ptt *p_ptt;
405 : : int i;
406 : :
407 [ # # ]: 0 : for_each_hwfn(edev, i) {
408 : 0 : p_hwfn = &edev->hwfns[i];
409 [ # # ]: 0 : if (IS_PF(edev)) {
410 : 0 : p_ptt = ecore_ptt_acquire(p_hwfn);
411 [ # # ]: 0 : if (!p_ptt) {
412 : 0 : DP_ERR(p_hwfn, "Can't acquire PTT\n");
413 : 0 : return -EAGAIN;
414 : : }
415 : : } else {
416 : : p_ptt = NULL;
417 : : }
418 : :
419 : 0 : rc = ecore_sp_pf_update_tunn_cfg(p_hwfn, p_ptt,
420 : : tunn_info, ECORE_SPQ_MODE_CB, NULL);
421 [ # # ]: 0 : if (IS_PF(edev))
422 : 0 : ecore_ptt_release(p_hwfn, p_ptt);
423 : :
424 [ # # ]: 0 : if (rc != ECORE_SUCCESS)
425 : : break;
426 : : }
427 : :
428 : : return rc;
429 : : }
430 : :
431 : : static int
432 : 0 : qede_vxlan_enable(struct rte_eth_dev *eth_dev, uint8_t clss,
433 : : bool enable)
434 : : {
435 : 0 : struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
436 : : struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
437 : : enum _ecore_status_t rc = ECORE_INVAL;
438 : : struct ecore_tunnel_info tunn;
439 : :
440 [ # # ]: 0 : if (qdev->vxlan.enable == enable)
441 : : return ECORE_SUCCESS;
442 : :
443 : : memset(&tunn, 0, sizeof(struct ecore_tunnel_info));
444 : 0 : tunn.vxlan.b_update_mode = true;
445 : 0 : tunn.vxlan.b_mode_enabled = enable;
446 : 0 : tunn.b_update_rx_cls = true;
447 : 0 : tunn.b_update_tx_cls = true;
448 : 0 : tunn.vxlan.tun_cls = clss;
449 : :
450 : 0 : tunn.vxlan_port.b_update_port = true;
451 [ # # ]: 0 : tunn.vxlan_port.port = enable ? QEDE_VXLAN_DEF_PORT : 0;
452 : :
453 : 0 : rc = qede_tunnel_update(qdev, &tunn);
454 [ # # ]: 0 : if (rc == ECORE_SUCCESS) {
455 : 0 : qdev->vxlan.enable = enable;
456 : 0 : qdev->vxlan.udp_port = (enable) ? QEDE_VXLAN_DEF_PORT : 0;
457 [ # # ]: 0 : DP_INFO(edev, "vxlan is %s, UDP port = %d\n",
458 : : enable ? "enabled" : "disabled", qdev->vxlan.udp_port);
459 : : } else {
460 : 0 : DP_ERR(edev, "Failed to update tunn_clss %u\n",
461 : : tunn.vxlan.tun_cls);
462 : : }
463 : :
464 : : return rc;
465 : : }
466 : :
467 : : static int
468 : 0 : qede_geneve_enable(struct rte_eth_dev *eth_dev, uint8_t clss,
469 : : bool enable)
470 : : {
471 [ # # ]: 0 : struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
472 : : struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
473 : : enum _ecore_status_t rc = ECORE_INVAL;
474 : : struct ecore_tunnel_info tunn;
475 : :
476 : : memset(&tunn, 0, sizeof(struct ecore_tunnel_info));
477 : 0 : tunn.l2_geneve.b_update_mode = true;
478 : 0 : tunn.l2_geneve.b_mode_enabled = enable;
479 : 0 : tunn.ip_geneve.b_update_mode = true;
480 : 0 : tunn.ip_geneve.b_mode_enabled = enable;
481 : 0 : tunn.l2_geneve.tun_cls = clss;
482 : 0 : tunn.ip_geneve.tun_cls = clss;
483 : 0 : tunn.b_update_rx_cls = true;
484 : 0 : tunn.b_update_tx_cls = true;
485 : :
486 : 0 : tunn.geneve_port.b_update_port = true;
487 [ # # ]: 0 : tunn.geneve_port.port = enable ? QEDE_GENEVE_DEF_PORT : 0;
488 : :
489 : 0 : rc = qede_tunnel_update(qdev, &tunn);
490 [ # # ]: 0 : if (rc == ECORE_SUCCESS) {
491 : 0 : qdev->geneve.enable = enable;
492 : 0 : qdev->geneve.udp_port = (enable) ? QEDE_GENEVE_DEF_PORT : 0;
493 [ # # ]: 0 : DP_INFO(edev, "GENEVE is %s, UDP port = %d\n",
494 : : enable ? "enabled" : "disabled", qdev->geneve.udp_port);
495 : : } else {
496 : 0 : DP_ERR(edev, "Failed to update tunn_clss %u\n",
497 : : clss);
498 : : }
499 : :
500 : 0 : return rc;
501 : : }
502 : :
503 : : int
504 : 0 : qede_udp_dst_port_del(struct rte_eth_dev *eth_dev,
505 : : struct rte_eth_udp_tunnel *tunnel_udp)
506 : : {
507 : 0 : struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
508 : : struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
509 : : struct ecore_tunnel_info tunn; /* @DPDK */
510 : : uint16_t udp_port;
511 : : int rc;
512 : :
513 : 0 : PMD_INIT_FUNC_TRACE(edev);
514 : :
515 : : memset(&tunn, 0, sizeof(tunn));
516 : :
517 [ # # # ]: 0 : switch (tunnel_udp->prot_type) {
518 : 0 : case RTE_ETH_TUNNEL_TYPE_VXLAN:
519 [ # # ]: 0 : if (qdev->vxlan.udp_port != tunnel_udp->udp_port) {
520 : 0 : DP_ERR(edev, "UDP port %u doesn't exist\n",
521 : : tunnel_udp->udp_port);
522 : 0 : return ECORE_INVAL;
523 : : }
524 : : udp_port = 0;
525 : :
526 : 0 : tunn.vxlan_port.b_update_port = true;
527 : : tunn.vxlan_port.port = udp_port;
528 : :
529 : 0 : rc = qede_tunnel_update(qdev, &tunn);
530 [ # # ]: 0 : if (rc != ECORE_SUCCESS) {
531 : 0 : DP_ERR(edev, "Unable to config UDP port %u\n",
532 : : tunn.vxlan_port.port);
533 : 0 : return rc;
534 : : }
535 : :
536 : 0 : qdev->vxlan.udp_port = udp_port;
537 : : /* If the request is to delete UDP port and if the number of
538 : : * VXLAN filters have reached 0 then VxLAN offload can be
539 : : * disabled.
540 : : */
541 [ # # # # ]: 0 : if (qdev->vxlan.enable && qdev->vxlan.num_filters == 0)
542 : 0 : return qede_vxlan_enable(eth_dev,
543 : : ECORE_TUNN_CLSS_MAC_VLAN, false);
544 : :
545 : : break;
546 : 0 : case RTE_ETH_TUNNEL_TYPE_GENEVE:
547 [ # # ]: 0 : if (qdev->geneve.udp_port != tunnel_udp->udp_port) {
548 : 0 : DP_ERR(edev, "UDP port %u doesn't exist\n",
549 : : tunnel_udp->udp_port);
550 : 0 : return ECORE_INVAL;
551 : : }
552 : :
553 : : udp_port = 0;
554 : :
555 : 0 : tunn.geneve_port.b_update_port = true;
556 : : tunn.geneve_port.port = udp_port;
557 : :
558 : 0 : rc = qede_tunnel_update(qdev, &tunn);
559 [ # # ]: 0 : if (rc != ECORE_SUCCESS) {
560 : 0 : DP_ERR(edev, "Unable to config UDP port %u\n",
561 : : tunn.vxlan_port.port);
562 : 0 : return rc;
563 : : }
564 : :
565 : 0 : qdev->vxlan.udp_port = udp_port;
566 : : /* If the request is to delete UDP port and if the number of
567 : : * GENEVE filters have reached 0 then GENEVE offload can be
568 : : * disabled.
569 : : */
570 [ # # # # ]: 0 : if (qdev->geneve.enable && qdev->geneve.num_filters == 0)
571 : 0 : return qede_geneve_enable(eth_dev,
572 : : ECORE_TUNN_CLSS_MAC_VLAN, false);
573 : :
574 : : break;
575 : :
576 : : default:
577 : : return ECORE_INVAL;
578 : : }
579 : :
580 : : return 0;
581 : : }
582 : :
583 : : int
584 : 0 : qede_udp_dst_port_add(struct rte_eth_dev *eth_dev,
585 : : struct rte_eth_udp_tunnel *tunnel_udp)
586 : : {
587 : 0 : struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
588 : : struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
589 : : struct ecore_tunnel_info tunn; /* @DPDK */
590 : : uint16_t udp_port;
591 : : int rc;
592 : :
593 : 0 : PMD_INIT_FUNC_TRACE(edev);
594 : :
595 : : memset(&tunn, 0, sizeof(tunn));
596 : :
597 [ # # # ]: 0 : switch (tunnel_udp->prot_type) {
598 : 0 : case RTE_ETH_TUNNEL_TYPE_VXLAN:
599 [ # # ]: 0 : if (qdev->vxlan.udp_port == tunnel_udp->udp_port) {
600 : 0 : DP_INFO(edev,
601 : : "UDP port %u for VXLAN was already configured\n",
602 : : tunnel_udp->udp_port);
603 : 0 : return ECORE_SUCCESS;
604 : : }
605 : :
606 : : /* Enable VxLAN tunnel with default MAC/VLAN classification if
607 : : * it was not enabled while adding VXLAN filter before UDP port
608 : : * update.
609 : : */
610 [ # # ]: 0 : if (!qdev->vxlan.enable) {
611 : 0 : rc = qede_vxlan_enable(eth_dev,
612 : : ECORE_TUNN_CLSS_MAC_VLAN, true);
613 [ # # ]: 0 : if (rc != ECORE_SUCCESS) {
614 : 0 : DP_ERR(edev, "Failed to enable VXLAN "
615 : : "prior to updating UDP port\n");
616 : 0 : return rc;
617 : : }
618 : : }
619 : 0 : udp_port = tunnel_udp->udp_port;
620 : :
621 : 0 : tunn.vxlan_port.b_update_port = true;
622 : 0 : tunn.vxlan_port.port = udp_port;
623 : :
624 : 0 : rc = qede_tunnel_update(qdev, &tunn);
625 [ # # ]: 0 : if (rc != ECORE_SUCCESS) {
626 : 0 : DP_ERR(edev, "Unable to config UDP port %u for VXLAN\n",
627 : : udp_port);
628 : 0 : return rc;
629 : : }
630 : :
631 : 0 : DP_INFO(edev, "Updated UDP port %u for VXLAN\n", udp_port);
632 : :
633 : 0 : qdev->vxlan.udp_port = udp_port;
634 : 0 : break;
635 : 0 : case RTE_ETH_TUNNEL_TYPE_GENEVE:
636 [ # # ]: 0 : if (qdev->geneve.udp_port == tunnel_udp->udp_port) {
637 : 0 : DP_INFO(edev,
638 : : "UDP port %u for GENEVE was already configured\n",
639 : : tunnel_udp->udp_port);
640 : 0 : return ECORE_SUCCESS;
641 : : }
642 : :
643 : : /* Enable GENEVE tunnel with default MAC/VLAN classification if
644 : : * it was not enabled while adding GENEVE filter before UDP port
645 : : * update.
646 : : */
647 [ # # ]: 0 : if (!qdev->geneve.enable) {
648 : 0 : rc = qede_geneve_enable(eth_dev,
649 : : ECORE_TUNN_CLSS_MAC_VLAN, true);
650 [ # # ]: 0 : if (rc != ECORE_SUCCESS) {
651 : 0 : DP_ERR(edev, "Failed to enable GENEVE "
652 : : "prior to updating UDP port\n");
653 : 0 : return rc;
654 : : }
655 : : }
656 : 0 : udp_port = tunnel_udp->udp_port;
657 : :
658 : 0 : tunn.geneve_port.b_update_port = true;
659 : 0 : tunn.geneve_port.port = udp_port;
660 : :
661 : 0 : rc = qede_tunnel_update(qdev, &tunn);
662 [ # # ]: 0 : if (rc != ECORE_SUCCESS) {
663 : 0 : DP_ERR(edev, "Unable to config UDP port %u for GENEVE\n",
664 : : udp_port);
665 : 0 : return rc;
666 : : }
667 : :
668 : 0 : DP_INFO(edev, "Updated UDP port %u for GENEVE\n", udp_port);
669 : :
670 : 0 : qdev->geneve.udp_port = udp_port;
671 : 0 : break;
672 : : default:
673 : : return ECORE_INVAL;
674 : : }
675 : :
676 : : return 0;
677 : : }
678 : :
679 : : static int
680 : 0 : qede_flow_validate_attr(__rte_unused struct rte_eth_dev *dev,
681 : : const struct rte_flow_attr *attr,
682 : : struct rte_flow_error *error)
683 : : {
684 [ # # ]: 0 : if (attr == NULL) {
685 : 0 : rte_flow_error_set(error, EINVAL,
686 : : RTE_FLOW_ERROR_TYPE_ATTR, NULL,
687 : : "NULL attribute");
688 : 0 : return -rte_errno;
689 : : }
690 : :
691 [ # # ]: 0 : if (attr->group != 0) {
692 : 0 : rte_flow_error_set(error, ENOTSUP,
693 : : RTE_FLOW_ERROR_TYPE_ATTR_GROUP, attr,
694 : : "Groups are not supported");
695 : 0 : return -rte_errno;
696 : : }
697 : :
698 [ # # ]: 0 : if (attr->priority != 0) {
699 : 0 : rte_flow_error_set(error, ENOTSUP,
700 : : RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, attr,
701 : : "Priorities are not supported");
702 : 0 : return -rte_errno;
703 : : }
704 : :
705 [ # # ]: 0 : if (attr->egress != 0) {
706 : 0 : rte_flow_error_set(error, ENOTSUP,
707 : : RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, attr,
708 : : "Egress is not supported");
709 : 0 : return -rte_errno;
710 : : }
711 : :
712 [ # # ]: 0 : if (attr->transfer != 0) {
713 : 0 : rte_flow_error_set(error, ENOTSUP,
714 : : RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, attr,
715 : : "Transfer is not supported");
716 : 0 : return -rte_errno;
717 : : }
718 : :
719 [ # # ]: 0 : if (attr->ingress == 0) {
720 : 0 : rte_flow_error_set(error, ENOTSUP,
721 : : RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, attr,
722 : : "Only ingress is supported");
723 : 0 : return -rte_errno;
724 : : }
725 : :
726 : : return 0;
727 : : }
728 : :
729 : : static int
730 : 0 : qede_flow_parse_pattern(__rte_unused struct rte_eth_dev *dev,
731 : : const struct rte_flow_item pattern[],
732 : : struct rte_flow_error *error,
733 : : struct rte_flow *flow)
734 : : {
735 : : bool l3 = false, l4 = false;
736 : :
737 [ # # ]: 0 : if (pattern == NULL) {
738 : 0 : rte_flow_error_set(error, EINVAL,
739 : : RTE_FLOW_ERROR_TYPE_ITEM_NUM, NULL,
740 : : "NULL pattern");
741 : 0 : return -rte_errno;
742 : : }
743 : :
744 [ # # ]: 0 : for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) {
745 [ # # ]: 0 : if (!pattern->spec) {
746 : 0 : rte_flow_error_set(error, EINVAL,
747 : : RTE_FLOW_ERROR_TYPE_ITEM,
748 : : pattern,
749 : : "Item spec not defined");
750 : 0 : return -rte_errno;
751 : : }
752 : :
753 [ # # ]: 0 : if (pattern->last) {
754 : 0 : rte_flow_error_set(error, EINVAL,
755 : : RTE_FLOW_ERROR_TYPE_ITEM,
756 : : pattern,
757 : : "Item last not supported");
758 : 0 : return -rte_errno;
759 : : }
760 : :
761 [ # # ]: 0 : if (pattern->mask) {
762 : 0 : rte_flow_error_set(error, EINVAL,
763 : : RTE_FLOW_ERROR_TYPE_ITEM,
764 : : pattern,
765 : : "Item mask not supported");
766 : 0 : return -rte_errno;
767 : : }
768 : :
769 : : /* Below validation is only for 4 tuple flow
770 : : * (GFT_PROFILE_TYPE_4_TUPLE)
771 : : * - src and dst L3 address (IPv4 or IPv6)
772 : : * - src and dst L4 port (TCP or UDP)
773 : : */
774 : :
775 [ # # # # : 0 : switch (pattern->type) {
# ]
776 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
777 : : l3 = true;
778 : :
779 [ # # ]: 0 : if (flow) {
780 : : const struct rte_flow_item_ipv4 *spec;
781 : :
782 : : spec = pattern->spec;
783 : 0 : flow->entry.tuple.src_ipv4 = spec->hdr.src_addr;
784 : 0 : flow->entry.tuple.dst_ipv4 = spec->hdr.dst_addr;
785 : 0 : flow->entry.tuple.eth_proto =
786 : : RTE_ETHER_TYPE_IPV4;
787 : : }
788 : : break;
789 : :
790 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
791 : : l3 = true;
792 : :
793 [ # # ]: 0 : if (flow) {
794 : : const struct rte_flow_item_ipv6 *spec;
795 : :
796 : : spec = pattern->spec;
797 : 0 : memcpy(flow->entry.tuple.src_ipv6,
798 : 0 : spec->hdr.src_addr, IPV6_ADDR_LEN);
799 : 0 : memcpy(flow->entry.tuple.dst_ipv6,
800 : 0 : spec->hdr.dst_addr, IPV6_ADDR_LEN);
801 : 0 : flow->entry.tuple.eth_proto =
802 : : RTE_ETHER_TYPE_IPV6;
803 : : }
804 : : break;
805 : :
806 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
807 : : l4 = true;
808 : :
809 [ # # ]: 0 : if (flow) {
810 : : const struct rte_flow_item_udp *spec;
811 : :
812 : : spec = pattern->spec;
813 : 0 : flow->entry.tuple.src_port =
814 : 0 : spec->hdr.src_port;
815 : 0 : flow->entry.tuple.dst_port =
816 : 0 : spec->hdr.dst_port;
817 : 0 : flow->entry.tuple.ip_proto = IPPROTO_UDP;
818 : : }
819 : : break;
820 : :
821 : 0 : case RTE_FLOW_ITEM_TYPE_TCP:
822 : : l4 = true;
823 : :
824 [ # # ]: 0 : if (flow) {
825 : : const struct rte_flow_item_tcp *spec;
826 : :
827 : : spec = pattern->spec;
828 : 0 : flow->entry.tuple.src_port =
829 : 0 : spec->hdr.src_port;
830 : 0 : flow->entry.tuple.dst_port =
831 : 0 : spec->hdr.dst_port;
832 : 0 : flow->entry.tuple.ip_proto = IPPROTO_TCP;
833 : : }
834 : :
835 : : break;
836 : 0 : default:
837 : 0 : rte_flow_error_set(error, EINVAL,
838 : : RTE_FLOW_ERROR_TYPE_ITEM,
839 : : pattern,
840 : : "Only 4 tuple (IPV4, IPV6, UDP and TCP) item types supported");
841 : 0 : return -rte_errno;
842 : : }
843 : : }
844 : :
845 [ # # ]: 0 : if (!(l3 && l4)) {
846 : 0 : rte_flow_error_set(error, EINVAL,
847 : : RTE_FLOW_ERROR_TYPE_ITEM,
848 : : pattern,
849 : : "Item types need to have both L3 and L4 protocols");
850 : 0 : return -rte_errno;
851 : : }
852 : :
853 : : return 0;
854 : : }
855 : :
856 : : static int
857 : 0 : qede_flow_parse_actions(struct rte_eth_dev *dev,
858 : : const struct rte_flow_action actions[],
859 : : struct rte_flow_error *error,
860 : : struct rte_flow *flow)
861 : : {
862 : : const struct rte_flow_action_queue *queue;
863 : :
864 [ # # ]: 0 : if (actions == NULL) {
865 : 0 : rte_flow_error_set(error, EINVAL,
866 : : RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
867 : : "NULL actions");
868 : 0 : return -rte_errno;
869 : : }
870 : :
871 [ # # ]: 0 : for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
872 [ # # # ]: 0 : switch (actions->type) {
873 : 0 : case RTE_FLOW_ACTION_TYPE_QUEUE:
874 : 0 : queue = actions->conf;
875 : :
876 [ # # ]: 0 : if (queue->index >= QEDE_RSS_COUNT(dev)) {
877 : 0 : rte_flow_error_set(error, EINVAL,
878 : : RTE_FLOW_ERROR_TYPE_ACTION,
879 : : actions,
880 : : "Bad QUEUE action");
881 : 0 : return -rte_errno;
882 : : }
883 : :
884 [ # # ]: 0 : if (flow)
885 : 0 : flow->entry.rx_queue = queue->index;
886 : :
887 : : break;
888 : 0 : case RTE_FLOW_ACTION_TYPE_DROP:
889 [ # # ]: 0 : if (flow)
890 : 0 : flow->entry.is_drop = true;
891 : : break;
892 : 0 : default:
893 : 0 : rte_flow_error_set(error, ENOTSUP,
894 : : RTE_FLOW_ERROR_TYPE_ACTION,
895 : : actions,
896 : : "Action is not supported - only ACTION_TYPE_QUEUE and ACTION_TYPE_DROP supported");
897 : 0 : return -rte_errno;
898 : : }
899 : : }
900 : :
901 : : return 0;
902 : : }
903 : :
904 : : static int
905 : 0 : qede_flow_parse(struct rte_eth_dev *dev,
906 : : const struct rte_flow_attr *attr,
907 : : const struct rte_flow_item patterns[],
908 : : const struct rte_flow_action actions[],
909 : : struct rte_flow_error *error,
910 : : struct rte_flow *flow)
911 : :
912 : : {
913 : : int rc = 0;
914 : :
915 : 0 : rc = qede_flow_validate_attr(dev, attr, error);
916 [ # # ]: 0 : if (rc)
917 : : return rc;
918 : :
919 : : /* parse and validate item pattern and actions.
920 : : * Given item list and actions will be translate to qede PMD
921 : : * specific arfs structure.
922 : : */
923 : 0 : rc = qede_flow_parse_pattern(dev, patterns, error, flow);
924 [ # # ]: 0 : if (rc)
925 : : return rc;
926 : :
927 : 0 : rc = qede_flow_parse_actions(dev, actions, error, flow);
928 : :
929 : 0 : return rc;
930 : : }
931 : :
932 : : static int
933 : 0 : qede_flow_validate(struct rte_eth_dev *dev,
934 : : const struct rte_flow_attr *attr,
935 : : const struct rte_flow_item patterns[],
936 : : const struct rte_flow_action actions[],
937 : : struct rte_flow_error *error)
938 : : {
939 : 0 : return qede_flow_parse(dev, attr, patterns, actions, error, NULL);
940 : : }
941 : :
942 : : static struct rte_flow *
943 : 0 : qede_flow_create(struct rte_eth_dev *dev,
944 : : const struct rte_flow_attr *attr,
945 : : const struct rte_flow_item pattern[],
946 : : const struct rte_flow_action actions[],
947 : : struct rte_flow_error *error)
948 : : {
949 : : struct rte_flow *flow = NULL;
950 : : int rc;
951 : :
952 : 0 : flow = rte_zmalloc("qede_rte_flow", sizeof(*flow), 0);
953 [ # # ]: 0 : if (flow == NULL) {
954 : 0 : rte_flow_error_set(error, ENOMEM,
955 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
956 : : "Failed to allocate memory");
957 : 0 : return NULL;
958 : : }
959 : :
960 : 0 : rc = qede_flow_parse(dev, attr, pattern, actions, error, flow);
961 [ # # ]: 0 : if (rc < 0) {
962 : 0 : rte_free(flow);
963 : 0 : return NULL;
964 : : }
965 : :
966 : 0 : rc = qede_config_arfs_filter(dev, &flow->entry, true);
967 [ # # ]: 0 : if (rc < 0) {
968 : 0 : rte_flow_error_set(error, rc,
969 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
970 : : "Failed to configure flow filter");
971 : 0 : rte_free(flow);
972 : 0 : return NULL;
973 : : }
974 : :
975 : : return flow;
976 : : }
977 : :
978 : : static int
979 : 0 : qede_flow_destroy(struct rte_eth_dev *eth_dev,
980 : : struct rte_flow *flow,
981 : : struct rte_flow_error *error)
982 : : {
983 : : int rc = 0;
984 : :
985 : 0 : rc = qede_config_arfs_filter(eth_dev, &flow->entry, false);
986 [ # # ]: 0 : if (rc < 0) {
987 : 0 : rte_flow_error_set(error, rc,
988 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
989 : : "Failed to delete flow filter");
990 : 0 : rte_free(flow);
991 : : }
992 : :
993 : 0 : return rc;
994 : : }
995 : :
996 : : static int
997 : 0 : qede_flow_flush(struct rte_eth_dev *eth_dev,
998 : : struct rte_flow_error *error)
999 : : {
1000 : 0 : struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
1001 : : struct qede_arfs_entry *tmp = NULL;
1002 : : int rc = 0;
1003 : :
1004 [ # # ]: 0 : while (!SLIST_EMPTY(&qdev->arfs_info.arfs_list_head)) {
1005 : : tmp = SLIST_FIRST(&qdev->arfs_info.arfs_list_head);
1006 : :
1007 : 0 : rc = qede_config_arfs_filter(eth_dev, tmp, false);
1008 [ # # ]: 0 : if (rc < 0)
1009 : 0 : rte_flow_error_set(error, rc,
1010 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1011 : : "Failed to flush flow filter");
1012 : : }
1013 : :
1014 : 0 : return rc;
1015 : : }
1016 : :
1017 : : const struct rte_flow_ops qede_flow_ops = {
1018 : : .validate = qede_flow_validate,
1019 : : .create = qede_flow_create,
1020 : : .destroy = qede_flow_destroy,
1021 : : .flush = qede_flow_flush,
1022 : : };
1023 : :
1024 : : int
1025 : 0 : qede_dev_flow_ops_get(struct rte_eth_dev *eth_dev,
1026 : : const struct rte_flow_ops **ops)
1027 : : {
1028 : 0 : struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
1029 : : struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
1030 : :
1031 [ # # ]: 0 : if (ECORE_IS_CMT(edev)) {
1032 : 0 : DP_ERR(edev, "flowdir is not supported in 100G mode\n");
1033 : 0 : return -ENOTSUP;
1034 : : }
1035 : :
1036 : 0 : *ops = &qede_flow_ops;
1037 : 0 : return 0;
1038 : : }
|