xref: /dpdk/drivers/net/sfc/sfc_dp.c (revision a0147be54763c09daca94eec7cb075214788ca65)
144c0947bSAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
2df1bfde4SAndrew Rybchenko  *
3*a0147be5SAndrew Rybchenko  * Copyright(c) 2019-2020 Xilinx, Inc.
4*a0147be5SAndrew 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>
11df1bfde4SAndrew Rybchenko #include <string.h>
12df1bfde4SAndrew Rybchenko #include <errno.h>
13df1bfde4SAndrew Rybchenko 
14df1bfde4SAndrew Rybchenko #include <rte_log.h>
15df1bfde4SAndrew Rybchenko 
16df1bfde4SAndrew Rybchenko #include "sfc_dp.h"
17fdceb100SIvan Malov #include "sfc_log.h"
18df1bfde4SAndrew Rybchenko 
19df1bfde4SAndrew Rybchenko void
20df1bfde4SAndrew Rybchenko sfc_dp_queue_init(struct sfc_dp_queue *dpq, uint16_t port_id, uint16_t queue_id,
21df1bfde4SAndrew Rybchenko 		  const struct rte_pci_addr *pci_addr)
22df1bfde4SAndrew Rybchenko {
23df1bfde4SAndrew Rybchenko 	dpq->port_id = port_id;
24df1bfde4SAndrew Rybchenko 	dpq->queue_id = queue_id;
25df1bfde4SAndrew Rybchenko 	dpq->pci_addr = *pci_addr;
26df1bfde4SAndrew Rybchenko }
27df1bfde4SAndrew Rybchenko 
28df1bfde4SAndrew Rybchenko struct sfc_dp *
29df1bfde4SAndrew Rybchenko sfc_dp_find_by_name(struct sfc_dp_list *head, enum sfc_dp_type type,
30df1bfde4SAndrew Rybchenko 		    const char *name)
31df1bfde4SAndrew Rybchenko {
32df1bfde4SAndrew Rybchenko 	struct sfc_dp *entry;
33df1bfde4SAndrew Rybchenko 
34df1bfde4SAndrew Rybchenko 	TAILQ_FOREACH(entry, head, links) {
35df1bfde4SAndrew Rybchenko 		if (entry->type != type)
36df1bfde4SAndrew Rybchenko 			continue;
37df1bfde4SAndrew Rybchenko 
38df1bfde4SAndrew Rybchenko 		if (strcmp(entry->name, name) == 0)
39df1bfde4SAndrew Rybchenko 			return entry;
40df1bfde4SAndrew Rybchenko 	}
41df1bfde4SAndrew Rybchenko 
42df1bfde4SAndrew Rybchenko 	return NULL;
43df1bfde4SAndrew Rybchenko }
44df1bfde4SAndrew Rybchenko 
45df1bfde4SAndrew Rybchenko struct sfc_dp *
46df1bfde4SAndrew Rybchenko sfc_dp_find_by_caps(struct sfc_dp_list *head, enum sfc_dp_type type,
47df1bfde4SAndrew Rybchenko 		    unsigned int avail_caps)
48df1bfde4SAndrew Rybchenko {
49df1bfde4SAndrew Rybchenko 	struct sfc_dp *entry;
50df1bfde4SAndrew Rybchenko 
51df1bfde4SAndrew Rybchenko 	TAILQ_FOREACH(entry, head, links) {
52df1bfde4SAndrew Rybchenko 		if (entry->type != type)
53df1bfde4SAndrew Rybchenko 			continue;
54df1bfde4SAndrew Rybchenko 
55df1bfde4SAndrew Rybchenko 		/* Take the first matching */
56df1bfde4SAndrew Rybchenko 		if (sfc_dp_match_hw_fw_caps(entry, avail_caps))
57df1bfde4SAndrew Rybchenko 			return entry;
58df1bfde4SAndrew Rybchenko 	}
59df1bfde4SAndrew Rybchenko 
60df1bfde4SAndrew Rybchenko 	return NULL;
61df1bfde4SAndrew Rybchenko }
62df1bfde4SAndrew Rybchenko 
63df1bfde4SAndrew Rybchenko int
64df1bfde4SAndrew Rybchenko sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry)
65df1bfde4SAndrew Rybchenko {
66df1bfde4SAndrew Rybchenko 	if (sfc_dp_find_by_name(head, entry->type, entry->name) != NULL) {
67fdceb100SIvan Malov 		SFC_GENERIC_LOG(ERR,
68fdceb100SIvan Malov 			"sfc %s dapapath '%s' already registered",
69dbdc8241SAndrew Rybchenko 			entry->type == SFC_DP_RX ? "Rx" :
70dbdc8241SAndrew Rybchenko 			entry->type == SFC_DP_TX ? "Tx" :
71dbdc8241SAndrew Rybchenko 			"unknown",
72df1bfde4SAndrew Rybchenko 			entry->name);
73df1bfde4SAndrew Rybchenko 		return EEXIST;
74df1bfde4SAndrew Rybchenko 	}
75df1bfde4SAndrew Rybchenko 
76df1bfde4SAndrew Rybchenko 	TAILQ_INSERT_TAIL(head, entry, links);
77df1bfde4SAndrew Rybchenko 
78df1bfde4SAndrew Rybchenko 	return 0;
79df1bfde4SAndrew Rybchenko }
80