xref: /dpdk/drivers/net/sfc/sfc_dp.c (revision 08966fe7f79fdaa5019b7559eebe84a1e3787b89)
144c0947bSAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
2df1bfde4SAndrew Rybchenko  *
398d26ef7SAndrew Rybchenko  * Copyright(c) 2019-2021 Xilinx, Inc.
4a0147be5SAndrew Rybchenko  * Copyright(c) 2017-2019 Solarflare Communications Inc.
5df1bfde4SAndrew Rybchenko  *
6df1bfde4SAndrew Rybchenko  * This software was jointly developed between OKTET Labs (under contract
7df1bfde4SAndrew Rybchenko  * for Solarflare) and Solarflare Communications, Inc.
8df1bfde4SAndrew Rybchenko  */
9df1bfde4SAndrew Rybchenko 
10df1bfde4SAndrew Rybchenko #include <sys/queue.h>
11*08966fe7STyler Retzlaff #include <stdalign.h>
12df1bfde4SAndrew Rybchenko #include <string.h>
13df1bfde4SAndrew Rybchenko #include <errno.h>
14df1bfde4SAndrew Rybchenko 
15fca8cba4SDavid Marchand #include <rte_ethdev.h>
16df1bfde4SAndrew Rybchenko #include <rte_log.h>
173f95dfb9SIgor Romanov #include <rte_mbuf_dyn.h>
183f95dfb9SIgor Romanov 
193f95dfb9SIgor Romanov #include "efx.h"
20df1bfde4SAndrew Rybchenko 
21df1bfde4SAndrew Rybchenko #include "sfc_dp.h"
22fdceb100SIvan Malov #include "sfc_log.h"
23df1bfde4SAndrew Rybchenko 
24df1bfde4SAndrew Rybchenko void
sfc_dp_queue_init(struct sfc_dp_queue * dpq,uint16_t port_id,uint16_t queue_id,const struct rte_pci_addr * pci_addr)25df1bfde4SAndrew Rybchenko sfc_dp_queue_init(struct sfc_dp_queue *dpq, uint16_t port_id, uint16_t queue_id,
26df1bfde4SAndrew Rybchenko 		  const struct rte_pci_addr *pci_addr)
27df1bfde4SAndrew Rybchenko {
28df1bfde4SAndrew Rybchenko 	dpq->port_id = port_id;
29df1bfde4SAndrew Rybchenko 	dpq->queue_id = queue_id;
30df1bfde4SAndrew Rybchenko 	dpq->pci_addr = *pci_addr;
31df1bfde4SAndrew Rybchenko }
32df1bfde4SAndrew Rybchenko 
33df1bfde4SAndrew Rybchenko struct sfc_dp *
sfc_dp_find_by_name(struct sfc_dp_list * head,enum sfc_dp_type type,const char * name)34df1bfde4SAndrew Rybchenko sfc_dp_find_by_name(struct sfc_dp_list *head, enum sfc_dp_type type,
35df1bfde4SAndrew Rybchenko 		    const char *name)
36df1bfde4SAndrew Rybchenko {
37df1bfde4SAndrew Rybchenko 	struct sfc_dp *entry;
38df1bfde4SAndrew Rybchenko 
39df1bfde4SAndrew Rybchenko 	TAILQ_FOREACH(entry, head, links) {
40df1bfde4SAndrew Rybchenko 		if (entry->type != type)
41df1bfde4SAndrew Rybchenko 			continue;
42df1bfde4SAndrew Rybchenko 
43df1bfde4SAndrew Rybchenko 		if (strcmp(entry->name, name) == 0)
44df1bfde4SAndrew Rybchenko 			return entry;
45df1bfde4SAndrew Rybchenko 	}
46df1bfde4SAndrew Rybchenko 
47df1bfde4SAndrew Rybchenko 	return NULL;
48df1bfde4SAndrew Rybchenko }
49df1bfde4SAndrew Rybchenko 
50df1bfde4SAndrew Rybchenko struct sfc_dp *
sfc_dp_find_by_caps(struct sfc_dp_list * head,enum sfc_dp_type type,unsigned int avail_caps)51df1bfde4SAndrew Rybchenko sfc_dp_find_by_caps(struct sfc_dp_list *head, enum sfc_dp_type type,
52df1bfde4SAndrew Rybchenko 		    unsigned int avail_caps)
53df1bfde4SAndrew Rybchenko {
54df1bfde4SAndrew Rybchenko 	struct sfc_dp *entry;
55df1bfde4SAndrew Rybchenko 
56df1bfde4SAndrew Rybchenko 	TAILQ_FOREACH(entry, head, links) {
57df1bfde4SAndrew Rybchenko 		if (entry->type != type)
58df1bfde4SAndrew Rybchenko 			continue;
59df1bfde4SAndrew Rybchenko 
60df1bfde4SAndrew Rybchenko 		/* Take the first matching */
61df1bfde4SAndrew Rybchenko 		if (sfc_dp_match_hw_fw_caps(entry, avail_caps))
62df1bfde4SAndrew Rybchenko 			return entry;
63df1bfde4SAndrew Rybchenko 	}
64df1bfde4SAndrew Rybchenko 
65df1bfde4SAndrew Rybchenko 	return NULL;
66df1bfde4SAndrew Rybchenko }
67df1bfde4SAndrew Rybchenko 
68df1bfde4SAndrew Rybchenko int
sfc_dp_register(struct sfc_dp_list * head,struct sfc_dp * entry)69df1bfde4SAndrew Rybchenko sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry)
70df1bfde4SAndrew Rybchenko {
71df1bfde4SAndrew Rybchenko 	if (sfc_dp_find_by_name(head, entry->type, entry->name) != NULL) {
72fdceb100SIvan Malov 		SFC_GENERIC_LOG(ERR,
737be78d02SJosh Soref 			"sfc %s datapath '%s' already registered",
74dbdc8241SAndrew Rybchenko 			entry->type == SFC_DP_RX ? "Rx" :
75dbdc8241SAndrew Rybchenko 			entry->type == SFC_DP_TX ? "Tx" :
76dbdc8241SAndrew Rybchenko 			"unknown",
77df1bfde4SAndrew Rybchenko 			entry->name);
78df1bfde4SAndrew Rybchenko 		return EEXIST;
79df1bfde4SAndrew Rybchenko 	}
80df1bfde4SAndrew Rybchenko 
81df1bfde4SAndrew Rybchenko 	TAILQ_INSERT_TAIL(head, entry, links);
82df1bfde4SAndrew Rybchenko 
83df1bfde4SAndrew Rybchenko 	return 0;
84df1bfde4SAndrew Rybchenko }
853f95dfb9SIgor Romanov 
863f95dfb9SIgor Romanov uint64_t sfc_dp_mport_override;
873f95dfb9SIgor Romanov int sfc_dp_mport_offset = -1;
883f95dfb9SIgor Romanov 
893f95dfb9SIgor Romanov int
sfc_dp_mport_register(void)903f95dfb9SIgor Romanov sfc_dp_mport_register(void)
913f95dfb9SIgor Romanov {
923f95dfb9SIgor Romanov 	static const struct rte_mbuf_dynfield mport = {
933f95dfb9SIgor Romanov 		.name = "rte_net_sfc_dynfield_mport",
943f95dfb9SIgor Romanov 		.size = sizeof(efx_mport_id_t),
95*08966fe7STyler Retzlaff 		.align = alignof(efx_mport_id_t),
963f95dfb9SIgor Romanov 	};
973f95dfb9SIgor Romanov 	static const struct rte_mbuf_dynflag mport_override = {
983f95dfb9SIgor Romanov 		.name = "rte_net_sfc_dynflag_mport_override",
993f95dfb9SIgor Romanov 	};
1003f95dfb9SIgor Romanov 
1013f95dfb9SIgor Romanov 	int field_offset;
1023f95dfb9SIgor Romanov 	int flag;
1033f95dfb9SIgor Romanov 
1043f95dfb9SIgor Romanov 	if (sfc_dp_mport_override != 0) {
1053f95dfb9SIgor Romanov 		SFC_GENERIC_LOG(INFO, "%s() already registered", __func__);
1063f95dfb9SIgor Romanov 		return 0;
1073f95dfb9SIgor Romanov 	}
1083f95dfb9SIgor Romanov 
1093f95dfb9SIgor Romanov 	field_offset = rte_mbuf_dynfield_register(&mport);
1103f95dfb9SIgor Romanov 	if (field_offset < 0) {
1113f95dfb9SIgor Romanov 		SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynfield",
1123f95dfb9SIgor Romanov 				__func__);
1133f95dfb9SIgor Romanov 		return -1;
1143f95dfb9SIgor Romanov 	}
1153f95dfb9SIgor Romanov 
1163f95dfb9SIgor Romanov 	flag = rte_mbuf_dynflag_register(&mport_override);
1173f95dfb9SIgor Romanov 	if (flag < 0) {
1183f95dfb9SIgor Romanov 		SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynflag",
1193f95dfb9SIgor Romanov 				__func__);
1203f95dfb9SIgor Romanov 		return -1;
1213f95dfb9SIgor Romanov 	}
1223f95dfb9SIgor Romanov 
1233f95dfb9SIgor Romanov 	sfc_dp_mport_offset = field_offset;
1243f95dfb9SIgor Romanov 	sfc_dp_mport_override = UINT64_C(1) << flag;
1253f95dfb9SIgor Romanov 
1263f95dfb9SIgor Romanov 	return 0;
1273f95dfb9SIgor Romanov }
1287e5b4798SIvan Malov 
129f55fe01fSIvan Malov int sfc_dp_ft_ctx_id_offset = -1;
130f55fe01fSIvan Malov uint64_t sfc_dp_ft_ctx_id_valid;
1317e5b4798SIvan Malov 
1327e5b4798SIvan Malov int
sfc_dp_ft_ctx_id_register(void)133f55fe01fSIvan Malov sfc_dp_ft_ctx_id_register(void)
1347e5b4798SIvan Malov {
135f55fe01fSIvan Malov 	static const struct rte_mbuf_dynfield ft_ctx_id = {
136f55fe01fSIvan Malov 		.name = "rte_net_sfc_dynfield_ft_ctx_id",
1377e5b4798SIvan Malov 		.size = sizeof(uint8_t),
138*08966fe7STyler Retzlaff 		.align = alignof(uint8_t),
1397e5b4798SIvan Malov 	};
1407e5b4798SIvan Malov 
1417e5b4798SIvan Malov 	int field_offset;
1427e5b4798SIvan Malov 
1437e5b4798SIvan Malov 	SFC_GENERIC_LOG(INFO, "%s() entry", __func__);
1447e5b4798SIvan Malov 
145f55fe01fSIvan Malov 	if (sfc_dp_ft_ctx_id_valid != 0) {
1467e5b4798SIvan Malov 		SFC_GENERIC_LOG(INFO, "%s() already registered", __func__);
1477e5b4798SIvan Malov 		return 0;
1487e5b4798SIvan Malov 	}
1497e5b4798SIvan Malov 
150f55fe01fSIvan Malov 	field_offset = rte_mbuf_dynfield_register(&ft_ctx_id);
1517e5b4798SIvan Malov 	if (field_offset < 0) {
152f55fe01fSIvan Malov 		SFC_GENERIC_LOG(ERR, "%s() failed to register ft_ctx_id dynfield",
1537e5b4798SIvan Malov 				__func__);
1547e5b4798SIvan Malov 		return -1;
1557e5b4798SIvan Malov 	}
1567e5b4798SIvan Malov 
157fca8cba4SDavid Marchand 	sfc_dp_ft_ctx_id_valid = rte_flow_restore_info_dynflag();
158f55fe01fSIvan Malov 	sfc_dp_ft_ctx_id_offset = field_offset;
1597e5b4798SIvan Malov 
1607e5b4798SIvan Malov 	SFC_GENERIC_LOG(INFO, "%s() done", __func__);
1617e5b4798SIvan Malov 
1627e5b4798SIvan Malov 	return 0;
1637e5b4798SIvan Malov }
164