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 --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 +- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 3 +- .../hisilicon/hns3/hns3pf/hclge_main.c | 93 ++++++++++++------- 3 files changed, 60 insertions(+), 38 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..77bd23e2c11e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -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; -- 2.33.0