qualcommax: qca_ppe: offload FLOW_ACTION_RX_QUEUE_MAPPING

tc reaches the classifier's queue action only through ethtool n-tuple.
Accept skbedit queue_mapping with skip_sw, as ice does, by redirecting the
frame to the CPU port and selecting that queue among the CPU port's twelve
unicast queues.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Julius Bairaktaris authored and Robert Marko committed 2026-10-18 12:50:08 +02:00
1 parent 167b1d8d1d
commit f89340fa5f
1 file changed
+18
@@ -949,6 +949,24 @@ static int ppe_acl_parse_action(struct qca_ppe_priv *priv,
act[3] |= PPE_ACL_QID_EN |
FIELD_PREP(PPE_ACL_QID, a->queue.index);
break;
case FLOW_ACTION_RX_QUEUE_MAPPING:
/* A receive queue of the port is a queue of the CPU
* port, so the frame is trapped and queued there.
*/
if (a->rx_queue >= PPE_CPU_UCAST_QUEUES) {
NL_SET_ERR_MSG_MOD(extack, "no such receive queue");
return -EOPNOTSUPP;
}
if (fwd) {
NL_SET_ERR_MSG_MOD(extack, "one forward command per rule");
return -EOPNOTSUPP;
}
fwd = true;
act[0] |= PPE_ACL_DEST_CHANGE_EN |
FIELD_PREP(PPE_ACL_FWD_CMD, PPE_ACL_FWD_RDT_CPU);
act[3] |= PPE_ACL_QID_EN |
FIELD_PREP(PPE_ACL_QID, a->rx_queue);
break;
case FLOW_ACTION_VLAN_POP:
/* The format bit beside the change enable is the whole
* choice: the frame leaves without the tag.