Commit a7cc1aa1 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Jakub Kicinski
Browse files

net: airoha: Introduce check_skb callback in ppe_dev ops



Export airoha_ppe_check_skb routine in ppe_dev ops. check_skb callback
will be used by the MT76 driver in order to offload the traffic received
by the wlan NIC and forwarded to the ethernet one.
Add rx_wlan parameter to airoha_ppe_check_skb routine signature.

Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20250823-airoha-en7581-wlan-rx-offload-v3-3-f78600ec3ed8@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f45fc18b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -698,7 +698,8 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)

		reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1);
		if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
			airoha_ppe_check_skb(eth->ppe, q->skb, hash);
			airoha_ppe_check_skb(&eth->ppe->dev, q->skb, hash,
					     false);

		done++;
		napi_gro_receive(&q->napi, q->skb);
+2 −6
Original line number Diff line number Diff line
@@ -229,10 +229,6 @@ struct airoha_hw_stats {
	u64 rx_len[7];
};

enum {
	PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f,
};

enum {
	AIROHA_FOE_STATE_INVALID,
	AIROHA_FOE_STATE_UNBIND,
@@ -622,8 +618,8 @@ static inline bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port)
bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
			      struct airoha_gdm_port *port);

void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb,
			  u16 hash);
void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
			  u16 hash, bool rx_wlan);
int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data);
int airoha_ppe_init(struct airoha_eth *eth);
void airoha_ppe_deinit(struct airoha_eth *eth);
+14 −11
Original line number Diff line number Diff line
@@ -616,7 +616,7 @@ static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e,

static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe,
				       struct airoha_foe_entry *e,
				       u32 hash)
				       u32 hash, bool rx_wlan)
{
	struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe);
	u32 ts = airoha_ppe_get_timestamp(ppe);
@@ -639,6 +639,7 @@ static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe,
		goto unlock;
	}

	if (!rx_wlan)
		airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash);

	if (hash < PPE_SRAM_NUM_ENTRIES) {
@@ -665,7 +666,7 @@ static void airoha_ppe_foe_remove_flow(struct airoha_ppe *ppe,
		e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_STATE;
		e->data.ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE,
					  AIROHA_FOE_STATE_INVALID);
		airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash);
		airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash, false);
		e->hash = 0xffff;
	}
	if (e->type == FLOW_TYPE_L2_SUBFLOW) {
@@ -704,7 +705,7 @@ static void airoha_ppe_foe_flow_remove_entry(struct airoha_ppe *ppe,
static int
airoha_ppe_foe_commit_subflow_entry(struct airoha_ppe *ppe,
				    struct airoha_flow_table_entry *e,
				    u32 hash)
				    u32 hash, bool rx_wlan)
{
	u32 mask = AIROHA_FOE_IB1_BIND_PACKET_TYPE | AIROHA_FOE_IB1_BIND_UDP;
	struct airoha_foe_entry *hwe_p, hwe;
@@ -745,14 +746,14 @@ airoha_ppe_foe_commit_subflow_entry(struct airoha_ppe *ppe,
	}

	hwe.bridge.data = e->data.bridge.data;
	airoha_ppe_foe_commit_entry(ppe, &hwe, hash);
	airoha_ppe_foe_commit_entry(ppe, &hwe, hash, rx_wlan);

	return 0;
}

static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe,
					struct sk_buff *skb,
					u32 hash)
					u32 hash, bool rx_wlan)
{
	struct airoha_flow_table_entry *e;
	struct airoha_foe_bridge br = {};
@@ -785,7 +786,7 @@ static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe,
		if (!airoha_ppe_foe_compare_entry(e, hwe))
			continue;

		airoha_ppe_foe_commit_entry(ppe, &e->data, hash);
		airoha_ppe_foe_commit_entry(ppe, &e->data, hash, rx_wlan);
		commit_done = true;
		e->hash = hash;
	}
@@ -797,7 +798,7 @@ static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe,
	e = rhashtable_lookup_fast(&ppe->l2_flows, &br,
				   airoha_l2_flow_table_params);
	if (e)
		airoha_ppe_foe_commit_subflow_entry(ppe, e, hash);
		airoha_ppe_foe_commit_subflow_entry(ppe, e, hash, rx_wlan);
unlock:
	spin_unlock_bh(&ppe_lock);
}
@@ -1301,9 +1302,10 @@ int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data)
	return err;
}

void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb,
			  u16 hash)
void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
			  u16 hash, bool rx_wlan)
{
	struct airoha_ppe *ppe = dev->priv;
	u16 now, diff;

	if (hash > PPE_HASH_MASK)
@@ -1315,7 +1317,7 @@ void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb,
		return;

	ppe->foe_check_time[hash] = now;
	airoha_ppe_foe_insert_entry(ppe, skb, hash);
	airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan);
}

void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
@@ -1404,6 +1406,7 @@ int airoha_ppe_init(struct airoha_eth *eth)
		return -ENOMEM;

	ppe->dev.ops.setup_tc_block_cb = airoha_ppe_setup_tc_block_cb;
	ppe->dev.ops.check_skb = airoha_ppe_check_skb;
	ppe->dev.priv = ppe;

	foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry);
+20 −0
Original line number Diff line number Diff line
@@ -9,10 +9,17 @@
#include <linux/spinlock.h>
#include <linux/workqueue.h>

enum {
	PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f,
};

struct airoha_ppe_dev {
	struct {
		int (*setup_tc_block_cb)(struct airoha_ppe_dev *dev,
					 void *type_data);
		void (*check_skb)(struct airoha_ppe_dev *dev,
				  struct sk_buff *skb, u16 hash,
				  bool rx_wlan);
	} ops;

	void *priv;
@@ -27,6 +34,13 @@ static inline int airoha_ppe_dev_setup_tc_block_cb(struct airoha_ppe_dev *dev,
{
	return dev->ops.setup_tc_block_cb(dev, type_data);
}

static inline void airoha_ppe_dev_check_skb(struct airoha_ppe_dev *dev,
					    struct sk_buff *skb,
					    u16 hash, bool rx_wlan)
{
	dev->ops.check_skb(dev, skb, hash, rx_wlan);
}
#else
static inline struct airoha_ppe_dev *airoha_ppe_get_dev(struct device *dev)
{
@@ -42,6 +56,12 @@ static inline int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev,
{
	return -EOPNOTSUPP;
}

static inline void airoha_ppe_dev_check_skb(struct airoha_ppe_dev *dev,
					    struct sk_buff *skb, u16 hash,
					    bool rx_wlan)
{
}
#endif

#define NPU_NUM_CORES		8