]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: hns3: refactor add_cls_flower to prepare for multiple actions
authorJijie Shao <shaojijie@huawei.com>
Wed, 10 Jun 2026 06:06:13 +0000 (14:06 +0800)
committerJakub Kicinski <kuba@kernel.org>
Sun, 14 Jun 2026 00:56:18 +0000 (17:56 -0700)
Remove the tc parameter from the add_cls_flower() ops callback and
refactor action parsing to support future extensions for SELECT_QUEUE
and DROP_PACKET actions.

Changes:
* Remove the tc parameter from the add_cls_flower() callback signature.
* Extract TC-based action parsing into hclge_get_tc_flower_action().
* Move the dissector->used_keys check from hclge_parse_cls_flower() to
  hclge_check_cls_flower(), and restrict ETH_ADDRS to
  HCLGE_FD_MODE_DEPTH_2K_WIDTH_400B_STAGE_1 mode since hardware only
  supports MAC matching there.
* Migrate error reporting from dev_err() to netlink extended ACK (extack).

Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Link: https://patch.msgid.link/20260610060618.834987-2-shaojijie@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

index d7c3df1958f392d06b2b44aa90640507abce626f..a724935b655a6f99a5da27b34d96bda99b1196fe 100644 (file)
@@ -778,7 +778,7 @@ struct hnae3_ae_ops {
                                 u32 len, u8 *data);
        bool (*get_cmdq_stat)(struct hnae3_handle *handle);
        int (*add_cls_flower)(struct hnae3_handle *handle,
-                             struct flow_cls_offload *cls_flower, int tc);
+                             struct flow_cls_offload *cls_flower);
        int (*del_cls_flower)(struct hnae3_handle *handle,
                              struct flow_cls_offload *cls_flower);
        bool (*cls_flower_active)(struct hnae3_handle *handle);
index 4c34a144d21c8448536b169cb11b85092b2012f1..6ecb32e28e79a88c6743bf630220bbf191b0319d 100644 (file)
@@ -2678,13 +2678,12 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data)
 static int hns3_setup_tc_cls_flower(struct hns3_nic_priv *priv,
                                    struct flow_cls_offload *flow)
 {
-       int tc = tc_classid_to_hwtc(priv->netdev, flow->classid);
        struct hnae3_handle *h = hns3_get_handle(priv->netdev);
 
        switch (flow->command) {
        case FLOW_CLS_REPLACE:
                if (h->ae_algo->ops->add_cls_flower)
-                       return h->ae_algo->ops->add_cls_flower(h, flow, tc);
+                       return h->ae_algo->ops->add_cls_flower(h, flow);
                break;
        case FLOW_CLS_DESTROY:
                if (h->ae_algo->ops->del_cls_flower)
index e17b92a411a22024dfc7ec56c387e4712d87003b..77bd23e2c11eb5038eb56e8eff41f456b24fa0d8 100644 (file)
@@ -7328,28 +7328,33 @@ static void hclge_get_cls_key_port(const struct flow_rule *flow,
        }
 }
 
+static int hclge_get_tc_flower_action(struct hclge_dev *hdev,
+                                     struct flow_cls_offload *cls_flower,
+                                     struct hclge_fd_rule *rule)
+{
+       struct netlink_ext_ack *extack = cls_flower->common.extack;
+       struct hnae3_handle *handle = &hdev->vport[0].nic;
+       int tc;
+
+       tc = tc_classid_to_hwtc(handle->netdev, cls_flower->classid);
+       if (tc < 0 || tc > hdev->tc_max) {
+               NL_SET_ERR_MSG_FMT_MOD(extack, "invalid traffic class: %d", tc);
+               return -EINVAL;
+       }
+
+       rule->action = HCLGE_FD_ACTION_SELECT_TC;
+       rule->cls_flower.tc = tc;
+       return 0;
+}
+
 static int hclge_parse_cls_flower(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 netlink_ext_ack *extack = cls_flower->common.extack;
-       struct flow_dissector *dissector = flow->match.dissector;
        int ret;
 
-       if (dissector->used_keys &
-           ~(BIT_ULL(FLOW_DISSECTOR_KEY_CONTROL) |
-             BIT_ULL(FLOW_DISSECTOR_KEY_BASIC) |
-             BIT_ULL(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
-             BIT_ULL(FLOW_DISSECTOR_KEY_VLAN) |
-             BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
-             BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
-             BIT_ULL(FLOW_DISSECTOR_KEY_PORTS))) {
-               dev_err(&hdev->pdev->dev, "unsupported key set: %#llx\n",
-                       dissector->used_keys);
-               return -EOPNOTSUPP;
-       }
-
        hclge_get_cls_key_basic(flow, rule);
        hclge_get_cls_key_mac(flow, rule);
        hclge_get_cls_key_vlan(flow, rule);
@@ -7364,51 +7369,65 @@ static int hclge_parse_cls_flower(struct hclge_dev *hdev,
 }
 
 static int hclge_check_cls_flower(struct hclge_dev *hdev,
-                                 struct flow_cls_offload *cls_flower, int tc)
+                                 struct flow_cls_offload *cls_flower)
 {
+       struct flow_rule *flow = flow_cls_offload_flow_rule(cls_flower);
+       struct netlink_ext_ack *extack = cls_flower->common.extack;
+       struct flow_dissector *dissector = flow->match.dissector;
        u32 prio = cls_flower->common.prio;
-
-       if (tc < 0 || tc > hdev->tc_max) {
-               dev_err(&hdev->pdev->dev, "invalid traffic class\n");
-               return -EINVAL;
-       }
+       u64 support_keys;
 
        if (prio == 0 ||
            prio > hdev->fd_cfg.rule_num[HCLGE_FD_STAGE_1]) {
-               dev_err(&hdev->pdev->dev,
-                       "prio %u should be in range[1, %u]\n",
-                       prio, hdev->fd_cfg.rule_num[HCLGE_FD_STAGE_1]);
+               NL_SET_ERR_MSG_FMT_MOD(extack,
+                                      "prio %u should be in range[1, %u]",
+                                      prio,
+                                      hdev->fd_cfg.rule_num[HCLGE_FD_STAGE_1]);
                return -EINVAL;
        }
 
        if (test_bit(prio - 1, hdev->fd_bmap)) {
-               dev_err(&hdev->pdev->dev, "prio %u is already used\n", prio);
+               NL_SET_ERR_MSG_FMT_MOD(extack,
+                                      "prio %u is already used", prio);
                return -EINVAL;
        }
+
+       support_keys = BIT_ULL(FLOW_DISSECTOR_KEY_CONTROL) |
+                      BIT_ULL(FLOW_DISSECTOR_KEY_BASIC) |
+                      BIT_ULL(FLOW_DISSECTOR_KEY_VLAN) |
+                      BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
+                      BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
+                      BIT_ULL(FLOW_DISSECTOR_KEY_PORTS);
+
+       if (hdev->fd_cfg.fd_mode == HCLGE_FD_MODE_DEPTH_2K_WIDTH_400B_STAGE_1)
+               support_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_ETH_ADDRS);
+
+       if (dissector->used_keys & ~support_keys) {
+               NL_SET_ERR_MSG_FMT_MOD(extack, "unsupported key set: %#llx",
+                                      dissector->used_keys);
+               return -EOPNOTSUPP;
+       }
+
        return 0;
 }
 
 static int hclge_add_cls_flower(struct hnae3_handle *handle,
-                               struct flow_cls_offload *cls_flower,
-                               int tc)
+                               struct flow_cls_offload *cls_flower)
 {
+       struct netlink_ext_ack *extack = cls_flower->common.extack;
        struct hclge_vport *vport = hclge_get_vport(handle);
        struct hclge_dev *hdev = vport->back;
        struct hclge_fd_rule *rule;
        int ret;
 
        if (!hnae3_ae_dev_fd_supported(hdev->ae_dev)) {
-               dev_err(&hdev->pdev->dev,
-                       "cls flower is not supported\n");
+               NL_SET_ERR_MSG_MOD(extack, "cls flower is not supported");
                return -EOPNOTSUPP;
        }
 
-       ret = hclge_check_cls_flower(hdev, cls_flower, tc);
-       if (ret) {
-               dev_err(&hdev->pdev->dev,
-                       "failed to check cls flower params, ret = %d\n", ret);
+       ret = hclge_check_cls_flower(hdev, cls_flower);
+       if (ret)
                return ret;
-       }
 
        rule = kzalloc_obj(*rule);
        if (!rule)
@@ -7420,8 +7439,12 @@ static int hclge_add_cls_flower(struct hnae3_handle *handle,
                return ret;
        }
 
-       rule->action = HCLGE_FD_ACTION_SELECT_TC;
-       rule->cls_flower.tc = tc;
+       ret = hclge_get_tc_flower_action(hdev, cls_flower, rule);
+       if (ret) {
+               kfree(rule);
+               return ret;
+       }
+
        rule->location = cls_flower->common.prio - 1;
        rule->vf_id = 0;
        rule->cls_flower.cookie = cls_flower->cookie;