1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) 2017 Solarflare Communications Inc. 5 * All rights reserved. 6 * 7 * This software was jointly developed between OKTET Labs (under contract 8 * for Solarflare) and Solarflare Communications, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/queue.h> 33 #include <string.h> 34 #include <errno.h> 35 36 #include <rte_log.h> 37 38 #include "sfc_dp.h" 39 40 void 41 sfc_dp_queue_init(struct sfc_dp_queue *dpq, uint16_t port_id, uint16_t queue_id, 42 const struct rte_pci_addr *pci_addr) 43 { 44 dpq->port_id = port_id; 45 dpq->queue_id = queue_id; 46 dpq->pci_addr = *pci_addr; 47 } 48 49 struct sfc_dp * 50 sfc_dp_find_by_name(struct sfc_dp_list *head, enum sfc_dp_type type, 51 const char *name) 52 { 53 struct sfc_dp *entry; 54 55 TAILQ_FOREACH(entry, head, links) { 56 if (entry->type != type) 57 continue; 58 59 if (strcmp(entry->name, name) == 0) 60 return entry; 61 } 62 63 return NULL; 64 } 65 66 struct sfc_dp * 67 sfc_dp_find_by_caps(struct sfc_dp_list *head, enum sfc_dp_type type, 68 unsigned int avail_caps) 69 { 70 struct sfc_dp *entry; 71 72 TAILQ_FOREACH(entry, head, links) { 73 if (entry->type != type) 74 continue; 75 76 /* Take the first matching */ 77 if (sfc_dp_match_hw_fw_caps(entry, avail_caps)) 78 return entry; 79 } 80 81 return NULL; 82 } 83 84 int 85 sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry) 86 { 87 if (sfc_dp_find_by_name(head, entry->type, entry->name) != NULL) { 88 rte_log(RTE_LOG_ERR, RTE_LOGTYPE_PMD, 89 "sfc %s dapapath '%s' already registered\n", 90 entry->type == SFC_DP_RX ? "Rx" : 91 entry->type == SFC_DP_TX ? "Tx" : 92 "unknown", 93 entry->name); 94 return EEXIST; 95 } 96 97 TAILQ_INSERT_TAIL(head, entry, links); 98 99 return 0; 100 } 101