From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id DE3B7A2EFC for ; Tue, 15 Oct 2019 10:24:25 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 4850D1E863; Tue, 15 Oct 2019 10:23:15 +0200 (CEST) Received: from mail.ntop.org (mail-digitalocean.ntop.org [167.99.215.164]) by dpdk.org (Postfix) with ESMTP id 4F9851DFED for ; Tue, 15 Oct 2019 10:22:48 +0200 (CEST) Received: from devele.ntop.org (net-93-145-196-230.cust.vodafonedsl.it [93.145.196.230]) by mail.ntop.org (Postfix) with ESMTPSA id EB8DF41C19; Tue, 15 Oct 2019 10:22:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ntop.org; s=mail; t=1571127768; bh=BcCYvxhGsOxALctq8WqbbX2ZmmMpiRM2shFVxTKHZ9M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ahW8V+x6lrJC5mUTPcVW87z7P69sSORLQiQyLnRzUzpxLLCxYL27xOyJFgl4ky9KC VoHCdF/vk8DN3lFYkuuYdj9mtXH6SwdJ/ULVdnuVT+7Mb9iBy3AQZPKeYSInYbl4CV WrsNZXAxmhtQvea2fxRaJHuyPxTqs0UMz0K6Y81I= From: Alfredo Cardigliano To: Alfredo Cardigliano , John McNamara , Marko Kovacevic Cc: dev@dpdk.org Date: Tue, 15 Oct 2019 10:22:29 +0200 Message-Id: <20191015082235.28639-12-cardigliano@ntop.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191015082235.28639-1-cardigliano@ntop.org> References: <20191015082235.28639-1-cardigliano@ntop.org> Subject: [dpdk-dev] [PATCH v2 11/17] net/ionic: add RX filters support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add support for managing RX filters based on MAC and VLAN. Hardware cannot provide the list of filters, thus we keep a local list. Add support for promisc and allmulticast modes. Signed-off-by: Alfredo Cardigliano Reviewed-by: Shannon Nelson --- doc/guides/nics/features/ionic.ini | 4 + drivers/net/ionic/Makefile | 1 + drivers/net/ionic/ionic_ethdev.c | 8 + drivers/net/ionic/ionic_lif.c | 255 +++++++++++++++++++++++++++- drivers/net/ionic/ionic_lif.h | 16 ++ drivers/net/ionic/ionic_rx_filter.c | 140 +++++++++++++++ drivers/net/ionic/ionic_rx_filter.h | 47 +++++ drivers/net/ionic/meson.build | 1 + 8 files changed, 468 insertions(+), 4 deletions(-) create mode 100644 drivers/net/ionic/ionic_rx_filter.c create mode 100644 drivers/net/ionic/ionic_rx_filter.h diff --git a/doc/guides/nics/features/ionic.ini b/doc/guides/nics/features/ionic.ini index c69e5cbed..3dd5dab45 100644 --- a/doc/guides/nics/features/ionic.ini +++ b/doc/guides/nics/features/ionic.ini @@ -8,6 +8,10 @@ Speed capabilities = Y Link status = Y Link status event = Y MTU update = Y +Promiscuous mode = Y +Allmulticast mode = Y +Unicast MAC filter = Y +VLAN filter = Y Linux UIO = Y Linux VFIO = Y x86-64 = Y diff --git a/drivers/net/ionic/Makefile b/drivers/net/ionic/Makefile index 8c402b17b..2ac214828 100644 --- a/drivers/net/ionic/Makefile +++ b/drivers/net/ionic/Makefile @@ -54,6 +54,7 @@ LDLIBS += -lrte_bus_pci # all source are stored in SRCS-y # SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_mac_api.c +SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_rx_filter.c SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_dev.c SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_ethdev.c SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_lif.c diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c index a0ab38435..cf02cdae3 100644 --- a/drivers/net/ionic/ionic_ethdev.c +++ b/drivers/net/ionic/ionic_ethdev.c @@ -50,6 +50,14 @@ static const struct eth_dev_ops ionic_eth_dev_ops = { .link_update = ionic_dev_link_update, .dev_set_link_up = ionic_dev_set_link_up, .dev_set_link_down = ionic_dev_set_link_down, + .mac_addr_add = ionic_dev_add_mac, + .mac_addr_remove = ionic_dev_remove_mac, + .mac_addr_set = ionic_dev_set_mac, + .vlan_filter_set = ionic_dev_vlan_filter_set, + .promiscuous_enable = ionic_dev_promiscuous_enable, + .promiscuous_disable = ionic_dev_promiscuous_disable, + .allmulticast_enable = ionic_dev_allmulticast_enable, + .allmulticast_disable = ionic_dev_allmulticast_disable, }; /* diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c index b6b730cef..0ab0f9e5e 100644 --- a/drivers/net/ionic/ionic_lif.c +++ b/drivers/net/ionic/ionic_lif.c @@ -9,6 +9,7 @@ #include "ionic_logs.h" #include "ionic_lif.h" #include "ionic_ethdev.h" +#include "ionic_rx_filter.h" static int ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr); static int ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr); @@ -85,19 +86,203 @@ ionic_lif_reset(struct ionic_lif *lif) static int ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr) { - ionic_init_print(INFO, "%s: stubbed\n", __func__); + struct ionic_admin_ctx ctx = { + .pending_work = true, + .cmd.rx_filter_add = { + .opcode = IONIC_CMD_RX_FILTER_ADD, + .match = IONIC_RX_FILTER_MATCH_MAC, + }, + }; + int err; - return 0; + memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN); + + err = ionic_adminq_post_wait(lif, &ctx); + + if (err) + return err; + + ionic_init_print(INFO, "rx_filter add (id %d)", + ctx.comp.rx_filter_add.filter_id); + + return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx); } static int ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr) { - ionic_init_print(INFO, "%s: stubbed\n", __func__); + struct ionic_admin_ctx ctx = { + .pending_work = true, + .cmd.rx_filter_del = { + .opcode = IONIC_CMD_RX_FILTER_DEL, + }, + }; + struct ionic_rx_filter *f; + int err; + + ionic_init_print_call(); + + rte_spinlock_lock(&lif->rx_filters.lock); + + f = ionic_rx_filter_by_addr(lif, addr); + + if (!f) { + rte_spinlock_unlock(&lif->rx_filters.lock); + return -ENOENT; + } + + ctx.cmd.rx_filter_del.filter_id = f->filter_id; + ionic_rx_filter_free(lif, f); + + rte_spinlock_unlock(&lif->rx_filters.lock); + + err = ionic_adminq_post_wait(lif, &ctx); + + if (err) + return err; + + ionic_init_print(INFO, "rx_filter del (id %d)", + ctx.cmd.rx_filter_del.filter_id); return 0; } +int +ionic_dev_add_mac(struct rte_eth_dev *eth_dev, + struct rte_ether_addr *mac_addr, + uint32_t index __rte_unused, uint32_t pool __rte_unused) +{ + struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + + ionic_init_print_call(); + + return ionic_lif_addr_add(lif, (const uint8_t *)mac_addr); +} + +void +ionic_dev_remove_mac(struct rte_eth_dev *eth_dev, uint32_t index __rte_unused) +{ + struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + struct ionic_adapter *adapter = lif->adapter; + + ionic_init_print_call(); + + if (index >= adapter->max_mac_addrs) { + ionic_init_print(WARNING, + "Index %u is above MAC filter limit %u", + index, adapter->max_mac_addrs); + return; + } + + if (!rte_is_valid_assigned_ether_addr(ð_dev->data->mac_addrs[index])) + return; + + ionic_lif_addr_del(lif, (const uint8_t *) + ð_dev->data->mac_addrs[index]); +} + +int +ionic_dev_set_mac(struct rte_eth_dev *eth_dev, struct rte_ether_addr *mac_addr) +{ + struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + + ionic_init_print_call(); + + if (mac_addr == NULL) { + ionic_init_print(NOTICE, "New mac is null"); + return -1; + } + + if (!rte_is_zero_ether_addr((struct rte_ether_addr *)lif->mac_addr)) { + ionic_init_print(INFO, "Deleting mac addr %pM", + lif->mac_addr); + ionic_lif_addr_del(lif, lif->mac_addr); + memset(lif->mac_addr, 0, ETH_ALEN); + } + + ionic_init_print(INFO, "Updating mac addr"); + + rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)lif->mac_addr); + + return ionic_lif_addr_add(lif, (const uint8_t *)mac_addr); +} + +static int +ionic_vlan_rx_add_vid(struct ionic_lif *lif, uint16_t vid) +{ + struct ionic_admin_ctx ctx = { + .pending_work = true, + .cmd.rx_filter_add = { + .opcode = IONIC_CMD_RX_FILTER_ADD, + .match = IONIC_RX_FILTER_MATCH_VLAN, + .vlan.vlan = vid, + }, + }; + int err; + + err = ionic_adminq_post_wait(lif, &ctx); + + if (err) + return err; + + ionic_init_print(INFO, "rx_filter add VLAN %d (id %d)", vid, + ctx.comp.rx_filter_add.filter_id); + + return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx); +} + +static int +ionic_vlan_rx_kill_vid(struct ionic_lif *lif, uint16_t vid) +{ + struct ionic_admin_ctx ctx = { + .pending_work = true, + .cmd.rx_filter_del = { + .opcode = IONIC_CMD_RX_FILTER_DEL, + }, + }; + struct ionic_rx_filter *f; + int err; + + ionic_init_print_call(); + + rte_spinlock_lock(&lif->rx_filters.lock); + + f = ionic_rx_filter_by_vlan(lif, vid); + if (!f) { + rte_spinlock_unlock(&lif->rx_filters.lock); + return -ENOENT; + } + + ctx.cmd.rx_filter_del.filter_id = f->filter_id; + ionic_rx_filter_free(lif, f); + rte_spinlock_unlock(&lif->rx_filters.lock); + + err = ionic_adminq_post_wait(lif, &ctx); + + if (err) + return err; + + ionic_init_print(INFO, "rx_filter del VLAN %d (id %d)", vid, + ctx.cmd.rx_filter_del.filter_id); + + return 0; +} + +int +ionic_dev_vlan_filter_set(struct rte_eth_dev *eth_dev, uint16_t vlan_id, + int on) +{ + struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + int err; + + if (on) + err = ionic_vlan_rx_add_vid(lif, vlan_id); + else + err = ionic_vlan_rx_kill_vid(lif, vlan_id); + + return err; +} + static void ionic_lif_rx_mode(struct ionic_lif *lif, uint32_t rx_mode) { @@ -137,6 +322,59 @@ ionic_set_rx_mode(struct ionic_lif *lif, uint32_t rx_mode) } } +int +ionic_dev_promiscuous_enable(struct rte_eth_dev *eth_dev) +{ + struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + uint32_t rx_mode = lif->rx_mode; + + ionic_init_print_call(); + + rx_mode |= IONIC_RX_MODE_F_PROMISC; + + ionic_set_rx_mode(lif, rx_mode); + + return 0; +} + +int +ionic_dev_promiscuous_disable(struct rte_eth_dev *eth_dev) +{ + struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + uint32_t rx_mode = lif->rx_mode; + + rx_mode &= ~IONIC_RX_MODE_F_PROMISC; + + ionic_set_rx_mode(lif, rx_mode); + + return 0; +} + +int +ionic_dev_allmulticast_enable(struct rte_eth_dev *eth_dev) +{ + struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + uint32_t rx_mode = lif->rx_mode; + + rx_mode |= IONIC_RX_MODE_F_ALLMULTI; + + ionic_set_rx_mode(lif, rx_mode); + + return 0; +} + +int +ionic_dev_allmulticast_disable(struct rte_eth_dev *eth_dev) +{ + struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + uint32_t rx_mode = lif->rx_mode; + + rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI; + + ionic_set_rx_mode(lif, rx_mode); + + return 0; +} int ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu) @@ -847,17 +1085,25 @@ ionic_lif_init(struct ionic_lif *lif) if (err) goto err_out_notifyq_deinit; - err = ionic_station_set(lif); + err = ionic_rx_filters_init(lif); if (err) goto err_out_notifyq_deinit; + err = ionic_station_set(lif); + + if (err) + goto err_out_rx_filter_deinit; + ionic_lif_set_name(lif); lif->state |= IONIC_LIF_F_INITED; return 0; +err_out_rx_filter_deinit: + ionic_rx_filters_deinit(lif); + err_out_notifyq_deinit: ionic_lif_qcq_deinit(lif, lif->notifyqcq); @@ -873,6 +1119,7 @@ ionic_lif_deinit(struct ionic_lif *lif) if (!(lif->state & IONIC_LIF_F_INITED)) return; + ionic_rx_filters_deinit(lif); ionic_lif_qcq_deinit(lif, lif->notifyqcq); ionic_lif_qcq_deinit(lif, lif->adminqcq); diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h index f7c51c9ec..e192186a6 100644 --- a/drivers/net/ionic/ionic_lif.h +++ b/drivers/net/ionic/ionic_lif.h @@ -12,6 +12,7 @@ #include "ionic_osdep.h" #include "ionic_dev.h" +#include "ionic_rx_filter.h" #define IONIC_ADMINQ_LENGTH 16 /* must be a power of two */ #define IONIC_NOTIFYQ_LENGTH 64 /* must be a power of two */ @@ -53,6 +54,7 @@ struct ionic_lif { rte_spinlock_t adminq_service_lock; struct ionic_qcq *adminqcq; struct ionic_qcq *notifyqcq; + struct ionic_rx_filters rx_filters; struct ionic_doorbell __iomem *kern_dbpage; uint64_t last_eid; uint64_t features; @@ -91,6 +93,20 @@ int ionic_qcq_service(struct ionic_qcq *qcq, int budget, ionic_cq_cb cb, int ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu); +int ionic_dev_add_mac(struct rte_eth_dev *eth_dev, + struct rte_ether_addr *mac_addr, + uint32_t index __rte_unused, uint32_t pool __rte_unused); +void ionic_dev_remove_mac(struct rte_eth_dev *eth_dev, + uint32_t index __rte_unused); +int ionic_dev_set_mac(struct rte_eth_dev *eth_dev, + struct rte_ether_addr *mac_addr); +int ionic_dev_vlan_filter_set(struct rte_eth_dev *eth_dev, uint16_t vlan_id, + int on); +int ionic_dev_promiscuous_enable(struct rte_eth_dev *dev); +int ionic_dev_promiscuous_disable(struct rte_eth_dev *dev); +int ionic_dev_allmulticast_enable(struct rte_eth_dev *dev); +int ionic_dev_allmulticast_disable(struct rte_eth_dev *dev); + void ionic_qcq_free(struct ionic_qcq *qcq); int ionic_qcq_enable(struct ionic_qcq *qcq); diff --git a/drivers/net/ionic/ionic_rx_filter.c b/drivers/net/ionic/ionic_rx_filter.c new file mode 100644 index 000000000..901f172dc --- /dev/null +++ b/drivers/net/ionic/ionic_rx_filter.c @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0 + * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved. + */ + +#include + +#include + +#include "ionic_lif.h" +#include "ionic_rx_filter.h" + +void +ionic_rx_filter_free(struct ionic_lif *lif, struct ionic_rx_filter *f) +{ + LIST_REMOVE(f, by_id); + LIST_REMOVE(f, by_hash); + rte_free(f); +} + +int +ionic_rx_filter_del(struct ionic_lif *lif, struct ionic_rx_filter *f) +{ + struct ionic_admin_ctx ctx = { + .pending_work = true, + .cmd.rx_filter_del = { + .opcode = IONIC_CMD_RX_FILTER_DEL, + .filter_id = f->filter_id, + }, + }; + + return ionic_adminq_post(lif, &ctx); +} + +int +ionic_rx_filters_init(struct ionic_lif *lif) +{ + uint32_t i; + + rte_spinlock_init(&lif->rx_filters.lock); + + for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { + LIST_INIT(&lif->rx_filters.by_hash[i]); + LIST_INIT(&lif->rx_filters.by_id[i]); + } + + return 0; +} + +void +ionic_rx_filters_deinit(struct ionic_lif *lif) +{ + struct ionic_rx_filter *f; + uint32_t i; + + for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { + while (!LIST_EMPTY(&lif->rx_filters.by_id[i])) { + f = LIST_FIRST(&lif->rx_filters.by_id[i]); + ionic_rx_filter_free(lif, f); + } + } +} + +int +ionic_rx_filter_save(struct ionic_lif *lif, uint32_t flow_id, + uint16_t rxq_index, + uint32_t hash, struct ionic_admin_ctx *ctx) +{ + struct ionic_rx_filter *f; + uint32_t key; + + f = rte_zmalloc("ionic", sizeof(*f), 0); + + if (!f) + return -ENOMEM; + + f->flow_id = flow_id; + f->filter_id = ctx->comp.rx_filter_add.filter_id; + f->rxq_index = rxq_index; + memcpy(&f->cmd, &ctx->cmd, sizeof(f->cmd)); + + switch (f->cmd.match) { + case IONIC_RX_FILTER_MATCH_VLAN: + key = f->cmd.vlan.vlan & IONIC_RX_FILTER_HLISTS_MASK; + break; + case IONIC_RX_FILTER_MATCH_MAC: + key = *(uint32_t *)f->cmd.mac.addr & + IONIC_RX_FILTER_HLISTS_MASK; + break; + case IONIC_RX_FILTER_MATCH_MAC_VLAN: + key = f->cmd.mac_vlan.vlan & IONIC_RX_FILTER_HLISTS_MASK; + break; + default: + return -EINVAL; + } + + rte_spinlock_lock(&lif->rx_filters.lock); + + LIST_INSERT_HEAD(&lif->rx_filters.by_hash[key], f, by_hash); + + key = f->filter_id & IONIC_RX_FILTER_HLISTS_MASK; + + LIST_INSERT_HEAD(&lif->rx_filters.by_id[key], f, by_id); + + rte_spinlock_unlock(&lif->rx_filters.lock); + + return 0; +} + +struct ionic_rx_filter * +ionic_rx_filter_by_vlan(struct ionic_lif *lif, uint16_t vid) +{ + uint32_t key = vid & IONIC_RX_FILTER_HLISTS_MASK; + struct ionic_rx_filter *f; + + LIST_FOREACH(f, &lif->rx_filters.by_hash[key], by_hash) { + if (f->cmd.match != IONIC_RX_FILTER_MATCH_VLAN) + continue; + if (f->cmd.vlan.vlan == vid) + return f; + } + + return NULL; +} + +struct ionic_rx_filter * +ionic_rx_filter_by_addr(struct ionic_lif *lif, const uint8_t *addr) +{ + const uint32_t key = *(const uint32_t *)addr & + IONIC_RX_FILTER_HLISTS_MASK; + struct ionic_rx_filter *f; + + LIST_FOREACH(f, &lif->rx_filters.by_hash[key], by_hash) { + if (f->cmd.match != IONIC_RX_FILTER_MATCH_MAC) + continue; + if (memcmp(addr, f->cmd.mac.addr, ETH_ALEN) == 0) + return f; + } + + return NULL; +} diff --git a/drivers/net/ionic/ionic_rx_filter.h b/drivers/net/ionic/ionic_rx_filter.h new file mode 100644 index 000000000..be56f0222 --- /dev/null +++ b/drivers/net/ionic/ionic_rx_filter.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 + * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved. + */ + +#ifndef _IONIC_RX_FILTER_H_ +#define _IONIC_RX_FILTER_H_ + +#include + +#include "ionic_osdep.h" +#include "ionic_if.h" + +#define IONIC_RXQ_INDEX_ANY (0xFFFF) +struct ionic_rx_filter { + uint32_t flow_id; + uint32_t filter_id; + uint16_t rxq_index; + struct ionic_rx_filter_add_cmd cmd; + LIST_ENTRY(ionic_rx_filter) by_hash; + LIST_ENTRY(ionic_rx_filter) by_id; +}; + +#define IONIC_RX_FILTER_HLISTS (1 << 10) +#define IONIC_RX_FILTER_HLISTS_MASK (IONIC_RX_FILTER_HLISTS - 1) +struct ionic_rx_filters { + rte_spinlock_t lock; + LIST_HEAD(rx_filters_by_hash, ionic_rx_filter) + by_hash[IONIC_RX_FILTER_HLISTS]; /* by pkt hash */ + LIST_HEAD(rx_filters_by_id, ionic_rx_filter) + by_id[IONIC_RX_FILTER_HLISTS]; /* by filter_id */ +}; + +struct ionic_admin_ctx; +struct ionic_lif; + +void ionic_rx_filter_free(struct ionic_lif *lif, struct ionic_rx_filter *f); +int ionic_rx_filter_del(struct ionic_lif *lif, struct ionic_rx_filter *f); +int ionic_rx_filters_init(struct ionic_lif *lif); +void ionic_rx_filters_deinit(struct ionic_lif *lif); +int ionic_rx_filter_save(struct ionic_lif *lif, uint32_t flow_id, + uint16_t rxq_index, uint32_t hash, struct ionic_admin_ctx *ctx); +struct ionic_rx_filter *ionic_rx_filter_by_vlan(struct ionic_lif *lif, + uint16_t vid); +struct ionic_rx_filter *ionic_rx_filter_by_addr(struct ionic_lif *lif, + const uint8_t *addr); + +#endif /* _IONIC_RX_FILTER_H_ */ diff --git a/drivers/net/ionic/meson.build b/drivers/net/ionic/meson.build index 0cf5a0cc7..ef202af7f 100644 --- a/drivers/net/ionic/meson.build +++ b/drivers/net/ionic/meson.build @@ -5,6 +5,7 @@ version = 1 sources = files( 'ionic_mac_api.c', + 'ionic_rx_filter.c', 'ionic_dev.c', 'ionic_ethdev.c', 'ionic_lif.c', -- 2.17.1