[PATCH V2 net-next 3/6] net: hns3: support two more actions for tc flow
From: Jijie Shao <shaojijie@huawei.com>
Date: 2026-05-23 10:55:32
Also in:
lkml
Subsystem:
hisilicon network subsystem 3 driver (hns3), hisilicon network subsystem driver, networking drivers, the rest · Maintainers:
Jian Shen, Jijie Shao, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Currently, the driver supports only one action:HCLGE_FD_ACTION_SELECT_TC. This patch adds support for HCLGE_FD_ACTION_SELECT_QUEUE and HCLGE_FD_ACTION_DROP_PACKET. A rule can have only one action. Therefore, the driver intercepts rules that have multiple actions or no action. Note: The driver considers cls_flower->classid as an action: HCLGE_FD_ACTION_SELECT_TC. Signed-off-by: Jijie Shao <shaojijie@huawei.com> --- .../hisilicon/hns3/hns3pf/hclge_main.c | 59 ++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 6eb4c6e4df4e..bbbc017a0fb7 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c@@ -7344,18 +7344,45 @@ static int hclge_get_tc_flower_action(struct hclge_dev *hdev, struct flow_cls_offload *cls_flower, struct hclge_fd_rule *rule) { + struct flow_rule *flow = flow_cls_offload_flow_rule(cls_flower); struct hnae3_handle *handle = &hdev->vport[0].nic; + struct flow_action *action = &flow->action; + struct flow_action_entry *act; int tc; - tc = tc_classid_to_hwtc(handle->netdev, cls_flower->classid); - if (tc < 0 || tc > hdev->tc_max) { - dev_err(&hdev->pdev->dev, "invalid traffic class: %d\n", tc); - return -EINVAL; + if (!flow_action_has_entries(&flow->action)) { + tc = tc_classid_to_hwtc(handle->netdev, cls_flower->classid); + if (tc < 0 || tc > hdev->tc_max) { + dev_err(&hdev->pdev->dev, + "invalid traffic class: %d\n", tc); + return -EINVAL; + } + + rule->action = HCLGE_FD_ACTION_SELECT_TC; + rule->cls_flower.tc = tc; + return 0; } - rule->action = HCLGE_FD_ACTION_SELECT_TC; - rule->cls_flower.tc = tc; - return 0; + act = &action->entries[0]; + switch (act->id) { + case FLOW_ACTION_RX_QUEUE_MAPPING: + if (act->rx_queue >= handle->kinfo.num_tqps) { + dev_err(&hdev->pdev->dev, + "queue id (%u) should be less than %u\n", + act->rx_queue, handle->kinfo.num_tqps - 1); + return -EINVAL; + } + + rule->queue_id = act->rx_queue; + rule->action = HCLGE_FD_ACTION_SELECT_QUEUE; + return 0; + case FLOW_ACTION_DROP: + rule->action = HCLGE_FD_ACTION_DROP_PACKET; + return 0; + default: + dev_err(&hdev->pdev->dev, "unsupported action(%d)\n", act->id); + return -EOPNOTSUPP; + } } static int hclge_parse_cls_flower(struct hclge_dev *hdev,
@@ -7412,6 +7439,24 @@ static int hclge_check_cls_flower(struct hclge_dev *hdev, return -EOPNOTSUPP; } + /* driver will parses classid into an action */ + if (cls_flower->classid && flow_action_has_entries(&flow->action)) { + dev_err(&hdev->pdev->dev, + "please not set classid and action together\n"); + return -EOPNOTSUPP; + } + + if (!flow_action_has_entries(&flow->action) && !cls_flower->classid) { + dev_err(&hdev->pdev->dev, "please set action or classid\n"); + return -EINVAL; + } + + if (flow_action_has_entries(&flow->action) && + !flow_offload_has_one_action(&flow->action)) { + dev_err(&hdev->pdev->dev, "unsupported multiple actions\n"); + return -EOPNOTSUPP; + } + return 0; }
--
2.33.0