Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright 2018-2022 Advanced Micro Devices, Inc. 3 : : */ 4 : : 5 : : #include <errno.h> 6 : : #include <stdbool.h> 7 : : 8 : : #include <rte_malloc.h> 9 : : 10 : : #include "ionic.h" 11 : : #include "ionic_lif.h" 12 : : #include "ionic_rx_filter.h" 13 : : 14 : : void 15 : 0 : ionic_rx_filter_free(struct ionic_rx_filter *f) 16 : : { 17 [ # # ]: 0 : LIST_REMOVE(f, by_id); 18 [ # # ]: 0 : LIST_REMOVE(f, by_hash); 19 : 0 : rte_free(f); 20 : 0 : } 21 : : 22 : : int 23 : 0 : ionic_rx_filters_init(struct ionic_lif *lif) 24 : : { 25 : : uint32_t i; 26 : : 27 : : rte_spinlock_init(&lif->rx_filters.lock); 28 : : 29 [ # # ]: 0 : for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { 30 : 0 : LIST_INIT(&lif->rx_filters.by_hash[i]); 31 : 0 : LIST_INIT(&lif->rx_filters.by_id[i]); 32 : : } 33 : : 34 : 0 : return 0; 35 : : } 36 : : 37 : : void 38 : 0 : ionic_rx_filters_deinit(struct ionic_lif *lif) 39 : : { 40 : : struct ionic_rx_filter *f; 41 : : uint32_t i; 42 : : 43 [ # # ]: 0 : for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { 44 [ # # ]: 0 : while (!LIST_EMPTY(&lif->rx_filters.by_id[i])) { 45 : : f = LIST_FIRST(&lif->rx_filters.by_id[i]); 46 : 0 : ionic_rx_filter_free(f); 47 : : } 48 : : } 49 : 0 : } 50 : : 51 : : int 52 : 0 : ionic_rx_filter_save(struct ionic_lif *lif, uint32_t flow_id, 53 : : uint16_t rxq_index, struct ionic_admin_ctx *ctx) 54 : : { 55 : : struct ionic_rx_filter *f; 56 : : uint32_t key; 57 : : 58 : 0 : f = rte_zmalloc("ionic", sizeof(*f), RTE_CACHE_LINE_SIZE); 59 [ # # ]: 0 : if (!f) 60 : : return -ENOMEM; 61 : : 62 : 0 : f->flow_id = flow_id; 63 : 0 : f->filter_id = rte_le_to_cpu_32(ctx->comp.rx_filter_add.filter_id); 64 : 0 : f->rxq_index = rxq_index; 65 [ # # # ]: 0 : memcpy(&f->cmd, &ctx->cmd, sizeof(f->cmd)); 66 : 0 : f->match = rte_le_to_cpu_16(f->cmd.match); 67 : : 68 [ # # # ]: 0 : switch (f->match) { 69 : 0 : case IONIC_RX_FILTER_MATCH_VLAN: 70 : 0 : key = rte_le_to_cpu_16(f->cmd.vlan.vlan); 71 : 0 : break; 72 : 0 : case IONIC_RX_FILTER_MATCH_MAC: 73 : : memcpy(&key, f->cmd.mac.addr, sizeof(key)); 74 : : break; 75 : : default: 76 : : return -EINVAL; 77 : : } 78 : : 79 : 0 : key &= IONIC_RX_FILTER_HLISTS_MASK; 80 : : 81 : 0 : rte_spinlock_lock(&lif->rx_filters.lock); 82 : : 83 [ # # ]: 0 : LIST_INSERT_HEAD(&lif->rx_filters.by_hash[key], f, by_hash); 84 : : 85 : 0 : key = f->filter_id & IONIC_RX_FILTER_HLISTS_MASK; 86 : : 87 [ # # ]: 0 : LIST_INSERT_HEAD(&lif->rx_filters.by_id[key], f, by_id); 88 : : 89 : : rte_spinlock_unlock(&lif->rx_filters.lock); 90 : : 91 : 0 : return 0; 92 : : } 93 : : 94 : : struct ionic_rx_filter * 95 : 0 : ionic_rx_filter_by_vlan(struct ionic_lif *lif, uint16_t vid) 96 : : { 97 : 0 : uint32_t key = vid & IONIC_RX_FILTER_HLISTS_MASK; 98 : : struct ionic_rx_filter *f; 99 : : __le16 vid_le = rte_cpu_to_le_16(vid); 100 : : 101 [ # # ]: 0 : LIST_FOREACH(f, &lif->rx_filters.by_hash[key], by_hash) { 102 [ # # ]: 0 : if (f->match != IONIC_RX_FILTER_MATCH_VLAN) 103 : 0 : continue; 104 [ # # ]: 0 : if (f->cmd.vlan.vlan == vid_le) 105 : 0 : return f; 106 : : } 107 : : 108 : : return NULL; 109 : : } 110 : : 111 : : struct ionic_rx_filter * 112 : 0 : ionic_rx_filter_by_addr(struct ionic_lif *lif, const uint8_t *addr) 113 : : { 114 : 0 : const uint32_t key = *(const uint32_t *)addr & 115 : : IONIC_RX_FILTER_HLISTS_MASK; 116 : : struct ionic_rx_filter *f; 117 : : 118 [ # # ]: 0 : LIST_FOREACH(f, &lif->rx_filters.by_hash[key], by_hash) { 119 [ # # ]: 0 : if (f->match != IONIC_RX_FILTER_MATCH_MAC) 120 : 0 : continue; 121 [ # # ]: 0 : if (memcmp(addr, f->cmd.mac.addr, RTE_ETHER_ADDR_LEN) == 0) 122 : 0 : return f; 123 : : } 124 : : 125 : : return NULL; 126 : : }