1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2 * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
7 #include <rte_malloc.h>
10 #include "ionic_rx_filter.h"
13 ionic_rx_filter_free(struct ionic_rx_filter *f)
15 LIST_REMOVE(f, by_id);
16 LIST_REMOVE(f, by_hash);
21 ionic_rx_filter_del(struct ionic_lif *lif, struct ionic_rx_filter *f)
23 struct ionic_admin_ctx ctx = {
25 .cmd.rx_filter_del = {
26 .opcode = IONIC_CMD_RX_FILTER_DEL,
27 .filter_id = f->filter_id,
31 return ionic_adminq_post(lif, &ctx);
35 ionic_rx_filters_init(struct ionic_lif *lif)
39 rte_spinlock_init(&lif->rx_filters.lock);
41 for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) {
42 LIST_INIT(&lif->rx_filters.by_hash[i]);
43 LIST_INIT(&lif->rx_filters.by_id[i]);
50 ionic_rx_filters_deinit(struct ionic_lif *lif)
52 struct ionic_rx_filter *f;
55 for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) {
56 while (!LIST_EMPTY(&lif->rx_filters.by_id[i])) {
57 f = LIST_FIRST(&lif->rx_filters.by_id[i]);
58 ionic_rx_filter_free(f);
64 ionic_rx_filter_save(struct ionic_lif *lif, uint32_t flow_id,
65 uint16_t rxq_index, struct ionic_admin_ctx *ctx)
67 struct ionic_rx_filter *f;
70 f = rte_zmalloc("ionic", sizeof(*f), 0);
76 f->filter_id = ctx->comp.rx_filter_add.filter_id;
77 f->rxq_index = rxq_index;
78 memcpy(&f->cmd, &ctx->cmd, sizeof(f->cmd));
80 switch (f->cmd.match) {
81 case IONIC_RX_FILTER_MATCH_VLAN:
82 key = f->cmd.vlan.vlan & IONIC_RX_FILTER_HLISTS_MASK;
84 case IONIC_RX_FILTER_MATCH_MAC:
85 memcpy(&key, f->cmd.mac.addr, sizeof(key));
86 key &= IONIC_RX_FILTER_HLISTS_MASK;
88 case IONIC_RX_FILTER_MATCH_MAC_VLAN:
89 key = f->cmd.mac_vlan.vlan & IONIC_RX_FILTER_HLISTS_MASK;
95 rte_spinlock_lock(&lif->rx_filters.lock);
97 LIST_INSERT_HEAD(&lif->rx_filters.by_hash[key], f, by_hash);
99 key = f->filter_id & IONIC_RX_FILTER_HLISTS_MASK;
101 LIST_INSERT_HEAD(&lif->rx_filters.by_id[key], f, by_id);
103 rte_spinlock_unlock(&lif->rx_filters.lock);
108 struct ionic_rx_filter *
109 ionic_rx_filter_by_vlan(struct ionic_lif *lif, uint16_t vid)
111 uint32_t key = vid & IONIC_RX_FILTER_HLISTS_MASK;
112 struct ionic_rx_filter *f;
114 LIST_FOREACH(f, &lif->rx_filters.by_hash[key], by_hash) {
115 if (f->cmd.match != IONIC_RX_FILTER_MATCH_VLAN)
117 if (f->cmd.vlan.vlan == vid)
124 struct ionic_rx_filter *
125 ionic_rx_filter_by_addr(struct ionic_lif *lif, const uint8_t *addr)
127 const uint32_t key = *(const uint32_t *)addr &
128 IONIC_RX_FILTER_HLISTS_MASK;
129 struct ionic_rx_filter *f;
131 LIST_FOREACH(f, &lif->rx_filters.by_hash[key], by_hash) {
132 if (f->cmd.match != IONIC_RX_FILTER_MATCH_MAC)
134 if (memcmp(addr, f->cmd.mac.addr, RTE_ETHER_ADDR_LEN) == 0)