Skip to content

Commit

Permalink
net: airoha: Introduce flowtable offload support
Browse files Browse the repository at this point in the history
Introduce netfilter flowtable integration in order to allow airoha_eth
driver to offload 5-tuple flower rules learned by the PPE module if the
user accelerates them using a nft configuration similar to the one reported
below:

table inet filter {
	flowtable ft {
		hook ingress priority filter
		devices = { lan1, lan2, lan3, lan4, eth1 }
		flags offload;
	}
	chain forward {
		type filter hook forward priority filter; policy accept;
		meta l4proto { tcp, udp } flow add @ft
	}
}

Tested-by: Sayantan Nandy <sayantan.nandy@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
Lorenzo Bianconi authored and Paolo Abeni committed Mar 4, 2025
1 parent 23290c7 commit 00a7678
Show file tree
Hide file tree
Showing 5 changed files with 1,314 additions and 7 deletions.
3 changes: 2 additions & 1 deletion drivers/net/ethernet/airoha/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
# Airoha for the Mediatek SoCs built-in ethernet macs
#

obj-$(CONFIG_NET_AIROHA) += airoha_eth.o
obj-$(CONFIG_NET_AIROHA) += airoha-eth.o
airoha-eth-y := airoha_eth.o airoha_ppe.o
obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o
60 changes: 59 additions & 1 deletion drivers/net/ethernet/airoha/airoha_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <linux/platform_device.h>
#include <linux/tcp.h>
#include <linux/u64_stats_sync.h>
#include <net/dsa.h>
#include <net/dst_metadata.h>
#include <net/page_pool/helpers.h>
#include <net/pkt_cls.h>
Expand Down Expand Up @@ -619,6 +618,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
while (done < budget) {
struct airoha_queue_entry *e = &q->entry[q->tail];
struct airoha_qdma_desc *desc = &q->desc[q->tail];
u32 hash, reason, msg1 = le32_to_cpu(desc->msg1);
dma_addr_t dma_addr = le32_to_cpu(desc->addr);
u32 desc_ctrl = le32_to_cpu(desc->ctrl);
struct airoha_gdm_port *port;
Expand Down Expand Up @@ -681,6 +681,15 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
&port->dsa_meta[sptag]->dst);
}

hash = FIELD_GET(AIROHA_RXD4_FOE_ENTRY, msg1);
if (hash != AIROHA_RXD4_FOE_ENTRY)
skb_set_hash(skb, jhash_1word(hash, 0),
PKT_HASH_TYPE_L4);

reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1);
if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
airoha_ppe_check_skb(eth->ppe, hash);

napi_gro_receive(&q->napi, skb);

done++;
Expand Down Expand Up @@ -1301,6 +1310,10 @@ static int airoha_hw_init(struct platform_device *pdev,
return err;
}

err = airoha_ppe_init(eth);
if (err)
return err;

set_bit(DEV_STATE_INITIALIZED, &eth->state);

return 0;
Expand Down Expand Up @@ -2168,6 +2181,47 @@ static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port,
return 0;
}

static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port,
struct flow_block_offload *f)
{
flow_setup_cb_t *cb = airoha_ppe_setup_tc_block_cb;
static LIST_HEAD(block_cb_list);
struct flow_block_cb *block_cb;

if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
return -EOPNOTSUPP;

f->driver_block_list = &block_cb_list;
switch (f->command) {
case FLOW_BLOCK_BIND:
block_cb = flow_block_cb_lookup(f->block, cb, port->dev);
if (block_cb) {
flow_block_cb_incref(block_cb);
return 0;
}
block_cb = flow_block_cb_alloc(cb, port->dev, port->dev, NULL);
if (IS_ERR(block_cb))
return PTR_ERR(block_cb);

flow_block_cb_incref(block_cb);
flow_block_cb_add(block_cb, f);
list_add_tail(&block_cb->driver_list, &block_cb_list);
return 0;
case FLOW_BLOCK_UNBIND:
block_cb = flow_block_cb_lookup(f->block, cb, port->dev);
if (!block_cb)
return -ENOENT;

if (!flow_block_cb_decref(block_cb)) {
flow_block_cb_remove(block_cb, f);
list_del(&block_cb->driver_list);
}
return 0;
default:
return -EOPNOTSUPP;
}
}

static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue)
{
struct net_device *dev = port->dev;
Expand Down Expand Up @@ -2251,6 +2305,9 @@ static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
return airoha_tc_setup_qdisc_ets(port, type_data);
case TC_SETUP_QDISC_HTB:
return airoha_tc_setup_qdisc_htb(port, type_data);
case TC_SETUP_BLOCK:
case TC_SETUP_FT:
return airoha_dev_setup_tc_block(port, type_data);
default:
return -EOPNOTSUPP;
}
Expand Down Expand Up @@ -2507,6 +2564,7 @@ static void airoha_remove(struct platform_device *pdev)
}
free_netdev(eth->napi_dev);

airoha_ppe_deinit(eth);
platform_set_drvdata(pdev, NULL);
}

Expand Down
Loading

0 comments on commit 00a7678

Please sign in to comment.