From patchwork Thu Nov 17 21:31:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 13047340 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 500D6C4332F for ; Thu, 17 Nov 2022 21:33:32 +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=/NEb9oDHuKcvPkfFOfLj79cnjRIIhkJuZsaoCWwBXQg=; b=qkW/cnp/nCXBzS EoCSpZW7/ZzefKzegPf7+i+ZuaQM2KDAUSdMcJrKK+mdZ+2nk3zIVE6oT2Pg3EIL6YJDyNOgS1r8a ujawZ+O649iTAKS6UXDoPz9GoVhDn8FsAiqXyKI52HI5cvnydpBTkHQ3ispj6oVRoHxN2+2FyyOB4 LM+tNvbD3/10CO8Ezm0hp+TSxay5ehlRPKTa8KjB8qJQdRlGF/JkEtW+UeP4goup1dNc6d4TxEkOu s4qRk2YPb2Ig908JWGE98sfKRU7Bk4Eg5owNQxMSy3TSCkA6YKbqjLyUPBTwz+2wbiMxytAfUFOKl 58KVaBPgPrx579mxI31A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1ovmUm-0002MU-KH; Thu, 17 Nov 2022 21:32:28 +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 1ovmU1-00026Q-Qm for linux-arm-kernel@lists.infradead.org; Thu, 17 Nov 2022 21:31:47 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1668720701; x=1700256701; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LyP2WXda0PH0GvrBBjC/Z80073SEoueZBYgNLXPx0P4=; b=RdwigRw93d+RI+9zJw+oSqUEBLasOoRzGy7hXoVKvcPZg7IuL3FtYhKL XrePKw8qZuUQYT8eYtyv5DWLNNJb4PwTG/oM2m83CHa1waB41BSqSoOOa r5MVJH+4zQyT/5TA0IBDTeg/JfR3NkSn9rn0Z2Lv8kKwg71MWTEVXNRKR UAgswwUaflBIcjXZ3JKEo/QsydwrS/hHuX4Ro77Fx3O3FxbDy7s+aQCte 6j1lcK/upeujxheCLUnJFtylysNg6pykHPt+rPlWAQfWYMn5HO01AepzU jUKE8n7i12hcv4+3/+GbUyb/4NtwEqKEkS94wVZrdyT9Gh2+so5SKopsk g==; X-IronPort-AV: E=Sophos;i="5.96,172,1665471600"; d="scan'208";a="187539465" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 17 Nov 2022 14:31:40 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) 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.12; Thu, 17 Nov 2022 14:31:40 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Thu, 17 Nov 2022 14:31:36 -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 Subject: [PATCH net-next v2 5/8] net: microchip: sparx5: Add VCAP rule debugFS support for the VCAP API Date: Thu, 17 Nov 2022 22:31:11 +0100 Message-ID: <20221117213114.699375-6-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221117213114.699375-1-steen.hegelund@microchip.com> References: <20221117213114.699375-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-20221117_133142_000456_0128DBB6 X-CRM114-Status: GOOD ( 18.31 ) 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 add support to show all rules in a VCAP instance. The information shown is: - rule id - address range - size - chain id - keyset name, subword size, register span - actionset name, subword size, register span - counter value - sticky bit (one bit width counter) Signed-off-by: Steen Hegelund --- .../net/ethernet/microchip/vcap/vcap_api.c | 15 ++- .../microchip/vcap/vcap_api_debugfs.c | 116 ++++++++++++++++++ .../microchip/vcap/vcap_api_private.h | 14 +++ 3 files changed, 141 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.c b/drivers/net/ethernet/microchip/vcap/vcap_api.c index 153e28e124bc..3da714e9639c 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api.c @@ -502,7 +502,7 @@ int vcap_api_check(struct vcap_control *ctrl) return 0; } -static void vcap_erase_cache(struct vcap_rule_internal *ri) +void vcap_erase_cache(struct vcap_rule_internal *ri) { ri->vctrl->ops->cache_erase(ri->admin); } @@ -578,7 +578,7 @@ int vcap_lookup_rule_by_cookie(struct vcap_control *vctrl, u64 cookie) EXPORT_SYMBOL_GPL(vcap_lookup_rule_by_cookie); /* Make a shallow copy of the rule without the fields */ -static struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri) +struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri) { struct vcap_rule_internal *duprule; @@ -782,9 +782,16 @@ const char *vcap_keyfield_name(struct vcap_control *vctrl, } EXPORT_SYMBOL_GPL(vcap_keyfield_name); +/* map actionset id to a string with the actionset name */ +const char *vcap_actionset_name(struct vcap_control *vctrl, + enum vcap_actionfield_set actionset) +{ + return vctrl->stats->actionfield_set_names[actionset]; +} + /* map action field id to a string with the action name */ -static const char *vcap_actionfield_name(struct vcap_control *vctrl, - enum vcap_action_field action) +const char *vcap_actionfield_name(struct vcap_control *vctrl, + enum vcap_action_field action) { return vctrl->stats->actionfield_names[action]; } diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c b/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c index 4a1ca26be901..b4bc32a08f2c 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c @@ -234,6 +234,106 @@ static int vcap_addr_keyset(struct vcap_control *vctrl, admin->cache.maskstream, false, 0); } +static int vcap_read_rule(struct vcap_rule_internal *ri) +{ + struct vcap_admin *admin = ri->admin; + int sw_idx, ent_idx = 0, act_idx = 0; + u32 addr = ri->addr; + + if (!ri->size || !ri->keyset_sw_regs || !ri->actionset_sw_regs) { + pr_err("%s:%d: rule is empty\n", __func__, __LINE__); + return -EINVAL; + } + vcap_erase_cache(ri); + /* Use the values in the streams to read the VCAP cache */ + for (sw_idx = 0; sw_idx < ri->size; sw_idx++, addr++) { + ri->vctrl->ops->update(ri->ndev, admin, VCAP_CMD_READ, + VCAP_SEL_ALL, addr); + ri->vctrl->ops->cache_read(ri->ndev, admin, + VCAP_SEL_ENTRY, ent_idx, + ri->keyset_sw_regs); + ri->vctrl->ops->cache_read(ri->ndev, admin, + VCAP_SEL_ACTION, act_idx, + ri->actionset_sw_regs); + if (sw_idx == 0) + ri->vctrl->ops->cache_read(ri->ndev, admin, + VCAP_SEL_COUNTER, + ri->counter_id, 0); + ent_idx += ri->keyset_sw_regs; + act_idx += ri->actionset_sw_regs; + } + return 0; +} + +static void vcap_show_admin_rule(struct vcap_control *vctrl, + struct vcap_admin *admin, + struct vcap_output_print *out, + struct vcap_rule_internal *ri) +{ + ri->counter.value = admin->cache.counter; + ri->counter.sticky = admin->cache.sticky; + out->prf(out->dst, + "rule: %u, addr: [%d,%d], X%d, ctr[%d]: %d, hit: %d\n", + ri->data.id, ri->addr, ri->addr + ri->size - 1, ri->size, + ri->counter_id, ri->counter.value, ri->counter.sticky); + out->prf(out->dst, " chain_id: %d\n", ri->data.vcap_chain_id); + out->prf(out->dst, " user: %d\n", ri->data.user); + out->prf(out->dst, " priority: %d\n", ri->data.priority); + out->prf(out->dst, " keyset: %s\n", + vcap_keyset_name(vctrl, ri->data.keyset)); + out->prf(out->dst, " actionset: %s\n", + vcap_actionset_name(vctrl, ri->data.actionset)); +} + +static void vcap_show_admin_info(struct vcap_control *vctrl, + struct vcap_admin *admin, + struct vcap_output_print *out) +{ + const struct vcap_info *vcap = &vctrl->vcaps[admin->vtype]; + + out->prf(out->dst, "name: %s\n", vcap->name); + out->prf(out->dst, "rows: %d\n", vcap->rows); + out->prf(out->dst, "sw_count: %d\n", vcap->sw_count); + out->prf(out->dst, "sw_width: %d\n", vcap->sw_width); + out->prf(out->dst, "sticky_width: %d\n", vcap->sticky_width); + out->prf(out->dst, "act_width: %d\n", vcap->act_width); + out->prf(out->dst, "default_cnt: %d\n", vcap->default_cnt); + out->prf(out->dst, "require_cnt_dis: %d\n", vcap->require_cnt_dis); + out->prf(out->dst, "version: %d\n", vcap->version); + out->prf(out->dst, "vtype: %d\n", admin->vtype); + out->prf(out->dst, "vinst: %d\n", admin->vinst); + out->prf(out->dst, "first_cid: %d\n", admin->first_cid); + out->prf(out->dst, "last_cid: %d\n", admin->last_cid); + out->prf(out->dst, "lookups: %d\n", admin->lookups); + out->prf(out->dst, "first_valid_addr: %d\n", admin->first_valid_addr); + out->prf(out->dst, "last_valid_addr: %d\n", admin->last_valid_addr); + out->prf(out->dst, "last_used_addr: %d\n", admin->last_used_addr); +} + +static int vcap_show_admin(struct vcap_control *vctrl, + struct vcap_admin *admin, + struct vcap_output_print *out) +{ + struct vcap_rule_internal *elem, *ri; + int ret = 0; + + vcap_show_admin_info(vctrl, admin, out); + list_for_each_entry(elem, &admin->rules, list) { + ri = vcap_dup_rule(elem); + if (IS_ERR(ri)) + goto free_rule; + /* Read data from VCAP */ + ret = vcap_read_rule(ri); + if (ret) + goto free_rule; + out->prf(out->dst, "\n"); + vcap_show_admin_rule(vctrl, admin, out, ri); +free_rule: + vcap_free_rule((struct vcap_rule *)ri); + } + return ret; +} + static int vcap_show_admin_raw(struct vcap_control *vctrl, struct vcap_admin *admin, struct vcap_output_print *out) @@ -313,6 +413,19 @@ void vcap_port_debugfs(struct device *dev, struct dentry *parent, } EXPORT_SYMBOL_GPL(vcap_port_debugfs); +/* Show the full VCAP instance data (rules with all fields) */ +static int vcap_debugfs_show(struct seq_file *m, void *unused) +{ + struct vcap_admin_debugfs_info *info = m->private; + struct vcap_output_print out = { + .prf = (void *)seq_printf, + .dst = m, + }; + + return vcap_show_admin(info->vctrl, info->admin, &out); +} +DEFINE_SHOW_ATTRIBUTE(vcap_debugfs); + /* Show the raw VCAP instance data (rules with address info) */ static int vcap_raw_debugfs_show(struct seq_file *m, void *unused) { @@ -347,6 +460,9 @@ struct dentry *vcap_debugfs(struct device *dev, struct dentry *parent, info->admin = admin; debugfs_create_file(name, 0444, dir, info, &vcap_raw_debugfs_fops); + sprintf(name, "%s_%d", vctrl->vcaps[admin->vtype].name, + admin->vinst); + debugfs_create_file(name, 0444, dir, info, &vcap_debugfs_fops); } return dir; } diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_private.h b/drivers/net/ethernet/microchip/vcap/vcap_api_private.h index 1ea25c5d0ca7..57309de463d7 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_private.h +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_private.h @@ -43,6 +43,10 @@ struct vcap_stream_iter { /* Check that the control has a valid set of callbacks */ int vcap_api_check(struct vcap_control *ctrl); +/* Make a shallow copy of the rule without the fields */ +struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri); +/* Erase the VCAP cache area used or encoding and decoding */ +void vcap_erase_cache(struct vcap_rule_internal *ri); /* Iterator functionality */ @@ -70,4 +74,14 @@ vcap_keyfield_typegroup(struct vcap_control *vctrl, const struct vcap_field *vcap_keyfields(struct vcap_control *vctrl, enum vcap_type vt, enum vcap_keyfield_set keyset); + +/* Actionset and actionfield functionality */ + +/* Map actionset id to a string with the actionset name */ +const char *vcap_actionset_name(struct vcap_control *vctrl, + enum vcap_actionfield_set actionset); +/* Map key field id to a string with the key name */ +const char *vcap_actionfield_name(struct vcap_control *vctrl, + enum vcap_action_field action); + #endif /* __VCAP_API_PRIVATE__ */