Currently, the driver supports only HCLGE_FD_ACTION_SELECT_TC configuration in hclge_add_cls_flower(). Therefore, the tc parameter is included in the function input parameters. The driver plans to extend this function to support HCLGE_FD_ACTION_SELECT_QUEUE and HCLGE_FD_ACTION_DROP_PACKET. Therefore, the tc parameter needs to be deleted from the input parameters of the function to ensure the universality of the function definition. In addition, this patch moves the check of dissector->used_keys from hclge_parse_cls_flower() to hclge_check_cls_flower(). Signed-off-by: Jijie Shao --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 +- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 3 +- .../hisilicon/hns3/hns3pf/hclge_main.c | 68 ++++++++++++------- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index d7c3df1958f3..a724935b655a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -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); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 4c34a144d21c..6ecb32e28e79 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -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) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index e17b92a411a2..89fff510befd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -7328,28 +7328,32 @@ 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 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) { + 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; +} + 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,15 +7368,12 @@ 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 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; - } - if (prio == 0 || prio > hdev->fd_cfg.rule_num[HCLGE_FD_STAGE_1]) { dev_err(&hdev->pdev->dev, @@ -7385,12 +7386,25 @@ static int hclge_check_cls_flower(struct hclge_dev *hdev, dev_err(&hdev->pdev->dev, "prio %u is already used\n", prio); return -EINVAL; } + + 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; + } + 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 hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; @@ -7403,7 +7417,7 @@ static int hclge_add_cls_flower(struct hnae3_handle *handle, return -EOPNOTSUPP; } - ret = hclge_check_cls_flower(hdev, cls_flower, tc); + ret = hclge_check_cls_flower(hdev, cls_flower); if (ret) { dev_err(&hdev->pdev->dev, "failed to check cls flower params, ret = %d\n", ret); @@ -7420,8 +7434,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; -- 2.33.0