From patchwork Tue Jan 24 10:45:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 13113783 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 53607C25B4E for ; Tue, 24 Jan 2023 10:47:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=YVUhO3sOl74grByFhHIkEcTo3O9e1VmXv8lBmH3EY+c=; b=G5G9j8kiwEYjl7 Kz6CYn0LkaQYHXg50y/kYJYs0NENFdKLUy++SQbD0rYsPePgyiXvkCFSKKG46JgZZqd0+9VAvcjIx uDRqsLmQnTSUNYsWx74xx/SwWrCFpUMyzYwuB3FfBuB8LKA4LW2jBWa1FqGHkokj2azsqrJxKKVor JAZSbsdh2pJTQwDCxJ95uFJVr+i3lV4JLc6mHCHZIt4a8ZWEYnHlquJqUc1atIbFaij8dVn4j934h rKO/ne3kaLdOrxdLcFSR/09AFFpDrusfpS9VhqHS1ELE07bJwDAbxDoPzGfsbaZl2I5h75NZvTZG8 nFXYakBpMqlVq1iM1FUw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1pKGoo-003Dh4-K9; Tue, 24 Jan 2023 10:46:23 +0000 Received: from esa.microchip.iphmx.com ([68.232.154.123]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1pKGo7-003DB5-A8 for linux-arm-kernel@lists.infradead.org; Tue, 24 Jan 2023 10:45:42 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1674557139; x=1706093139; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZEVz+bONQiUVbca9h/hm2Jb4RyNnx7ZykTq4+rFMOmM=; b=jxdYaOywa/Bd9IIei3pMlaXX7A9DQ9/VWKFZIh5XefU+T5mUPCBMq5n7 XDbb1/ZD/mTmppLWlLPhT0AJ40I1sxzymKjmxcwOcetOFKhGJre3jPuKQ Gt9gcG5YmVy1ka56JCZm3kGN2pY8GsocL2Z921ZbMQ0U2gjY5EdBx9aRy N892nZh3C5bKbOSd5UdkctvYDJ7pf4LJvIgtdHYSx4mkTv3+ieym2b9sn BST9PHX8UEQhFZPscJesFx76J6DRYsy9WSZ8bClkMLIN/a/886/nrA5l/ wwp/mOkzh3yHaApZEXWtw1dEg7/ilB+qZAN+g4RpKCIUcIJem8XNEZsgV A==; X-IronPort-AV: E=Sophos;i="5.97,242,1669100400"; d="scan'208";a="133744288" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 24 Jan 2023 03:45:38 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16; Tue, 24 Jan 2023 03:45:37 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.16 via Frontend Transport; Tue, 24 Jan 2023 03:45:33 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen , Dan Carpenter , Michael Walle Subject: [PATCH net-next v2 5/8] net: microchip: sparx5: Add TC filter chaining support for IS0 and IS2 VCAPs Date: Tue, 24 Jan 2023 11:45:08 +0100 Message-ID: <20230124104511.293938-6-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230124104511.293938-1-steen.hegelund@microchip.com> References: <20230124104511.293938-1-steen.hegelund@microchip.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230124_024539_531358_CED78BA9 X-CRM114-Status: GOOD ( 25.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This allows rules to be chained between VCAP instances, e.g. from IS0 Lookup 0 to IS0 Lookup 1, or from one of the IS0 Lookups to one of the IS2 Lookups. Chaining from an IS2 Lookup to another IS2 Lookup is not supported in the hardware. Signed-off-by: Steen Hegelund --- .../microchip/sparx5/sparx5_tc_flower.c | 93 ++++++++++++++++++- .../net/ethernet/microchip/vcap/vcap_api.c | 43 ++++++++- .../ethernet/microchip/vcap/vcap_api_client.h | 2 + 3 files changed, 136 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c index 72bc2733b662..b32ea01ff935 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c @@ -850,6 +850,84 @@ static int sparx5_tc_set_actionset(struct vcap_admin *admin, return err; } +/* Add the VCAP key to match on for a rule target value */ +static int sparx5_tc_add_rule_link_target(struct vcap_admin *admin, + struct vcap_rule *vrule, + int target_cid) +{ + int link_val = target_cid % VCAP_CID_LOOKUP_SIZE; + int err; + + if (!link_val) + return 0; + + switch (admin->vtype) { + case VCAP_TYPE_IS0: + /* Add NXT_IDX key for chaining rules between IS0 instances */ + err = vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_GEN_IDX_SEL, + 1, /* enable */ + ~0); + if (err) + return err; + return vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_GEN_IDX, + link_val, /* target */ + ~0); + case VCAP_TYPE_IS2: + /* Add PAG key for chaining rules from IS0 */ + return vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_PAG, + link_val, /* target */ + ~0); + default: + break; + } + return 0; +} + +/* Add the VCAP action that adds a target value to a rule */ +static int sparx5_tc_add_rule_link(struct vcap_control *vctrl, + struct vcap_admin *admin, + struct vcap_rule *vrule, + int from_cid, int to_cid) +{ + struct vcap_admin *to_admin = vcap_find_admin(vctrl, to_cid); + int diff, err = 0; + + diff = vcap_chain_offset(vctrl, from_cid, to_cid); + if (!(to_admin && diff > 0)) { + pr_err("%s:%d: unsupported chain direction: %d\n", + __func__, __LINE__, to_cid); + return -EINVAL; + } + if (admin->vtype == VCAP_TYPE_IS0 && + to_admin->vtype == VCAP_TYPE_IS0) { + /* Between IS0 instances the G_IDX value is used */ + err = vcap_rule_add_action_u32(vrule, VCAP_AF_NXT_IDX, diff); + if (err) + goto out; + err = vcap_rule_add_action_u32(vrule, VCAP_AF_NXT_IDX_CTRL, + 1); /* Replace */ + if (err) + goto out; + } else if (admin->vtype == VCAP_TYPE_IS0 && + to_admin->vtype == VCAP_TYPE_IS2) { + /* Between IS0 and IS2 the PAG value is used */ + err = vcap_rule_add_action_u32(vrule, VCAP_AF_PAG_VAL, diff); + if (err) + goto out; + err = vcap_rule_add_action_u32(vrule, + VCAP_AF_PAG_OVERRIDE_MASK, + 0xff); + if (err) + goto out; + } else { + pr_err("%s:%d: unsupported chain destination: %d\n", + __func__, __LINE__, to_cid); + err = -EOPNOTSUPP; + } +out: + return err; +} + static int sparx5_tc_flower_replace(struct net_device *ndev, struct flow_cls_offload *fco, struct vcap_admin *admin) @@ -885,10 +963,21 @@ static int sparx5_tc_flower_replace(struct net_device *ndev, if (err) goto out; + err = sparx5_tc_add_rule_link_target(admin, vrule, + fco->common.chain_index); + if (err) + goto out; + frule = flow_cls_offload_flow_rule(fco); flow_action_for_each(idx, act, &frule->action) { switch (act->id) { case FLOW_ACTION_TRAP: + if (admin->vtype != VCAP_TYPE_IS2) { + NL_SET_ERR_MSG_MOD(fco->common.extack, + "Trap action not supported in this VCAP"); + err = -EOPNOTSUPP; + goto out; + } err = vcap_rule_add_action_bit(vrule, VCAP_AF_CPU_COPY_ENA, VCAP_BIT_1); @@ -917,7 +1006,9 @@ static int sparx5_tc_flower_replace(struct net_device *ndev, err = sparx5_tc_set_actionset(admin, vrule); if (err) goto out; - /* Links between VCAPs will be added later */ + sparx5_tc_add_rule_link(vctrl, admin, vrule, + fco->common.chain_index, + act->chain_index); break; default: NL_SET_ERR_MSG_MOD(fco->common.extack, diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.c b/drivers/net/ethernet/microchip/vcap/vcap_api.c index c740e83d9c20..258b0a397d37 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api.c @@ -1601,6 +1601,40 @@ struct vcap_admin *vcap_find_admin(struct vcap_control *vctrl, int cid) } EXPORT_SYMBOL_GPL(vcap_find_admin); +/* Is this the last admin instance ordered by chain id */ +static bool vcap_admin_is_last(struct vcap_control *vctrl, + struct vcap_admin *admin) +{ + struct vcap_admin *iter, *last = NULL; + int max_cid = 0; + + list_for_each_entry(iter, &vctrl->list, list) { + if (iter->first_cid > max_cid) { + last = iter; + max_cid = iter->first_cid; + } + } + if (!last) + return false; + + return admin == last; +} + +/* Calculate the value used for chaining VCAP rules */ +int vcap_chain_offset(struct vcap_control *vctrl, int from_cid, int to_cid) +{ + int diff = to_cid - from_cid; + + if (diff < 0) /* Wrong direction */ + return diff; + to_cid %= VCAP_CID_LOOKUP_SIZE; + if (to_cid == 0) /* Destination aligned to a lookup == no chaining */ + return 0; + diff %= VCAP_CID_LOOKUP_SIZE; /* Limit to a value within a lookup */ + return diff; +} +EXPORT_SYMBOL_GPL(vcap_chain_offset); + /* Is the next chain id in one of the following lookups * For now this does not support filters linked to other filters using * keys and actions. That will be added later. @@ -2825,6 +2859,7 @@ static int vcap_enable_rule(struct vcap_rule_internal *ri) static int vcap_enable_rules(struct vcap_control *vctrl, struct net_device *ndev, int chain) { + int next_chain = chain + VCAP_CID_LOOKUP_SIZE; struct vcap_rule_internal *ri; struct vcap_admin *admin; int err = 0; @@ -2836,8 +2871,11 @@ static int vcap_enable_rules(struct vcap_control *vctrl, /* Found the admin, now find the offloadable rules */ mutex_lock(&admin->lock); list_for_each_entry(ri, &admin->rules, list) { - if (ri->data.vcap_chain_id != chain) + /* Is the rule in the lookup defined by the chain */ + if (!(ri->data.vcap_chain_id >= chain && + ri->data.vcap_chain_id < next_chain)) { continue; + } if (ri->ndev != ndev) continue; @@ -3054,6 +3092,9 @@ bool vcap_is_last_chain(struct vcap_control *vctrl, int cid) if (!admin) return false; + if (!vcap_admin_is_last(vctrl, admin)) + return false; + /* This must be the last lookup in this VCAP type */ lookup = vcap_chain_id_to_lookup(admin, cid); return lookup == admin->lookups - 1; diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h index 2cdcd3b56b30..69ea230ba8a1 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h @@ -217,6 +217,8 @@ const struct vcap_field *vcap_lookup_keyfield(struct vcap_rule *rule, enum vcap_key_field key); /* Find a rule id with a provided cookie */ int vcap_lookup_rule_by_cookie(struct vcap_control *vctrl, u64 cookie); +/* Calculate the value used for chaining VCAP rules */ +int vcap_chain_offset(struct vcap_control *vctrl, int from_cid, int to_cid); /* Is the next chain id in the following lookup, possible in another VCAP */ bool vcap_is_next_lookup(struct vcap_control *vctrl, int cur_cid, int next_cid); /* Is this chain id the last lookup of all VCAPs */