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