From patchwork Sun Aug 5 13:01:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 10556141 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 41C9213BB for ; Sun, 5 Aug 2018 13:04:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2BDF22993B for ; Sun, 5 Aug 2018 13:04:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2046D29967; Sun, 5 Aug 2018 13:04:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2CFDB2993B for ; Sun, 5 Aug 2018 13:04:49 +0000 (UTC) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41k1G72CgZzF3HY for ; Sun, 5 Aug 2018 23:04:47 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="fCxtHHuq"; dkim-atps=neutral X-Original-To: linux-mlxsw@lists.ozlabs.org Delivered-To: linux-mlxsw@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (mailfrom) smtp.mailfrom=resnulli.us (client-ip=2a00:1450:4864:20::42c; helo=mail-wr1-x42c.google.com; envelope-from=jiri@resnulli.us; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="fCxtHHuq"; dkim-atps=neutral Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41k1Fr6D0YzF3HG for ; Sun, 5 Aug 2018 23:04:32 +1000 (AEST) Received: by mail-wr1-x42c.google.com with SMTP id v14-v6so9759454wro.5 for ; Sun, 05 Aug 2018 06:04:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=c4Y9xW6Y636Jmh+oTTi3KtDGZ8mcsucwytRxyaqeepw=; b=fCxtHHuqh4goZUjZM6W5nv5XPh0YdDrjKV06y0AaHYnINwM3GBZFf5AeZ0TietYOap 0l7hy0jjw40EiqEVwj3PUu34uwZ98PSOwEJ5QJ0fZayYjvWtX76lA4iFIauJQl5UAkmo mOuuaz2cRHmKWJJc0wxtopzttVg4TKwnVz7FQSkEAbhQsZFSK4NXy0e0j/ipB7Iqfu1T 3kk5bss6I7MAWcmbaVYngL+NPpCVAIVhAnXYHiDF9pUOkV+CnMJtLd8740qS+Afds4N2 0iCKMod19Ae4EDKcWoxnIQthJOmAwnX6kHKRlnJHwDK0LtDYbFgEXytcE2d7giS2HnJT zCtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=c4Y9xW6Y636Jmh+oTTi3KtDGZ8mcsucwytRxyaqeepw=; b=jjxi5nDSmhVig1b1sKaLB7hSgfctmgO2lTz8YheTnLBgCw4FZXoI+HtYlHxP3HeRi4 mpXaVqUH0XBv57sWwBp0RwRi4H2/Cd/PeT5YLoEUHb1qGj6Mk+ua4y125Jonsls8kP+Q MgTzozpKDn8a5vpe0kCAQTRKEe6qp7qFeS0FVOV40kAd3qSJy7XmYsCIrvNkpqZAwT/o F/U1NrKh6fyC/RFb7zJ82+/plFBTZ5OL1L40UmZP12g1lORUptlSWyaqxBXdTimus5EJ PbvdHRIB41uZ6SGnKDVOXvj0BqTOZN587WWJu6Jci6+wOb0j9wRDkM/hx55OFqSFa7jZ 2Ccg== X-Gm-Message-State: AOUpUlEDno/SBDdm4mPS1YRnBKY+hZydEVPjKnR0m5uT5YRPGrfigLs/ Yyp7xZLs9id/e6GZUq64a5DBcw== X-Google-Smtp-Source: AAOMgpfj/cT5wnOX0jh6EhnouyGDsOl2hvLa0iqFiQAn0fmve2KhgI7YlkQXQ1c1Yf72cs6Fwb+eGQ== X-Received: by 2002:adf:bf10:: with SMTP id p16-v6mr6935908wrh.235.1533474269670; Sun, 05 Aug 2018 06:04:29 -0700 (PDT) Received: from localhost (static-cl188134168102.unet.cz. [188.134.168.102]) by smtp.gmail.com with ESMTPSA id i15-v6sm7595139wro.7.2018.08.05.06.04.29 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 05 Aug 2018 06:04:29 -0700 (PDT) From: Jiri Pirko To: linux-internal@mellanox.com Subject: [patch net-next/mlxsw internal preRFC 3/3] mlxsw: spectrum: acl: Implement delta for ERP Date: Sun, 5 Aug 2018 15:01:33 +0200 Message-Id: <20180805130133.6812-4-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180805130133.6812-1-jiri@resnulli.us> References: <20180805130133.6812-1-jiri@resnulli.us> X-BeenThere: linux-mlxsw@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: mlxsw driver development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: linux-mlxsw-bounces+patchwork-linux-mlxsw=patchwork.kernel.org@lists.ozlabs.org X-Virus-Scanned: ClamAV using ClamSMTP From: Jiri Pirko Allow ERP sharing for multiple mask. Do it by properly implementing delta_create() objagg object. Use the computed delta info for inserting rules in A-TCAM. Signed-off-by: Jiri Pirko --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 8 +- .../ethernet/mellanox/mlxsw/spectrum_acl_atcam.c | 15 +++- .../net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c | 91 +++++++++++++++++++++- .../ethernet/mellanox/mlxsw/spectrum_acl_tcam.h | 14 ++++ 4 files changed, 122 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 6e8b619b769b..35b2bb5bc0fa 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -2765,8 +2765,9 @@ static inline void mlxsw_reg_ptce3_pack(char *payload, bool valid, u32 priority, const char *tcam_region_info, const char *key, u8 erp_id, - bool large_exists, u32 lkey_id, - u32 action_pointer) + u16 delta_start, u8 delta_mask, + u8 delta_value, bool large_exists, + u32 lkey_id, u32 action_pointer) { MLXSW_REG_ZERO(ptce3, payload); mlxsw_reg_ptce3_v_set(payload, valid); @@ -2775,6 +2776,9 @@ static inline void mlxsw_reg_ptce3_pack(char *payload, bool valid, mlxsw_reg_ptce3_tcam_region_info_memcpy_to(payload, tcam_region_info); mlxsw_reg_ptce3_flex2_key_blocks_memcpy_to(payload, key); mlxsw_reg_ptce3_erp_id_set(payload, erp_id); + mlxsw_reg_ptce3_delta_start_set(payload, delta_start); + mlxsw_reg_ptce3_delta_mask_set(payload, delta_mask); + mlxsw_reg_ptce3_delta_value_set(payload, delta_value); mlxsw_reg_ptce3_large_exists_set(payload, large_exists); mlxsw_reg_ptce3_large_entry_key_id_set(payload, lkey_id); mlxsw_reg_ptce3_action_pointer_set(payload, action_pointer); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c index 5a0b88707269..5500f7b1a137 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c @@ -378,9 +378,12 @@ mlxsw_sp_acl_atcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_atcam_entry *aentry, struct mlxsw_sp_acl_rule_info *rulei) { + const struct mlxsw_sp_acl_erp_mask_delta *delta = + mlxsw_sp_acl_erp_mask_delta(aentry->erp_mask); struct mlxsw_sp_acl_tcam_region *region = aregion->region; u8 erp_id = mlxsw_sp_acl_erp_mask_erp_id(aentry->erp_mask); struct mlxsw_sp_acl_atcam_lkey_id *lkey_id; + char *enc_key = aentry->ht_key.enc_key; char ptce3_pl[MLXSW_REG_PTCE3_LEN]; u32 kvdl_index, priority; int err; @@ -397,7 +400,8 @@ mlxsw_sp_acl_atcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp, kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block); mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_WRITE, priority, region->tcam_region_info, - aentry->ht_key.enc_key, erp_id, + enc_key, erp_id, delta->start, delta->mask, + mlxsw_sp_acl_erp_mask_delta_value(delta, enc_key), refcount_read(&lkey_id->refcnt) != 1, lkey_id->id, kvdl_index); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce3), ptce3_pl); @@ -416,14 +420,19 @@ mlxsw_sp_acl_atcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_atcam_region *aregion, struct mlxsw_sp_acl_atcam_entry *aentry) { + const struct mlxsw_sp_acl_erp_mask_delta *delta = + mlxsw_sp_acl_erp_mask_delta(aentry->erp_mask); struct mlxsw_sp_acl_atcam_lkey_id *lkey_id = aentry->lkey_id; struct mlxsw_sp_acl_tcam_region *region = aregion->region; u8 erp_id = mlxsw_sp_acl_erp_mask_erp_id(aentry->erp_mask); + char *enc_key = aentry->ht_key.enc_key; char ptce3_pl[MLXSW_REG_PTCE3_LEN]; mlxsw_reg_ptce3_pack(ptce3_pl, false, MLXSW_REG_PTCE3_OP_WRITE_WRITE, 0, - region->tcam_region_info, aentry->ht_key.enc_key, - erp_id, refcount_read(&lkey_id->refcnt) != 1, + region->tcam_region_info, enc_key, + erp_id, delta->start, delta->mask, + mlxsw_sp_acl_erp_mask_delta_value(delta, enc_key), + refcount_read(&lkey_id->refcnt) != 1, lkey_id->id, 0); mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce3), ptce3_pl); aregion->ops->lkey_id_put(aregion, lkey_id); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c index f11a50b36927..ac57bf6d3026 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c @@ -978,14 +978,103 @@ u8 mlxsw_sp_acl_erp_mask_erp_id(const struct mlxsw_sp_acl_erp_mask *erp_mask) return erp->id; } +static const struct mlxsw_sp_acl_erp_mask_delta +mlxsw_sp_acl_erp_mask_delta_default = {}; + +const struct mlxsw_sp_acl_erp_mask_delta * +mlxsw_sp_acl_erp_mask_delta(const struct mlxsw_sp_acl_erp_mask *erp_mask) +{ + struct objagg_obj *objagg_obj = (struct objagg_obj *) erp_mask; + const struct mlxsw_sp_acl_erp_mask_delta *delta; + + delta = objagg_obj_delta_priv(objagg_obj); + if (!delta) + delta = &mlxsw_sp_acl_erp_mask_delta_default; + return delta; +} + +static int mlxsw_sp_acl_erp_delta_get(struct mlxsw_sp_acl_erp_key *parent_key, + struct mlxsw_sp_acl_erp_key *key, + u16 *delta_start, u8 *delta_mask) +{ + size_t len = sizeof(key->mask); + int index_start = -1; + int offset = 0; + u16 pmask; + u16 mask; + int i; + + /* The difference between 2 masks can be up to 8 consecutive bits. */ + for (i = 0; i < len; i++) { + if (parent_key->mask[i] == key->mask[i]) + continue; + if (index_start == -1) + index_start = i; + else if (index_start != i - 1) + return -EINVAL; + } + if (index_start == -1) { + /* The masks are the same, this cannot happen. + * That means the caller is broken. + */ + WARN_ON(1); + *delta_start = 0; + *delta_mask = 0; + return 0; + } + pmask = parent_key->mask[index_start] << 8; + mask = key->mask[index_start] << 8; + if (index_start + 1 < len) { + pmask |= (unsigned char) parent_key->mask[index_start + 1]; + mask |= (unsigned char) key->mask[index_start + 1]; + } + + if ((pmask ^ mask) & pmask) + return -EINVAL; + mask &= ~pmask; + while (!(mask & (1 << (15 - offset)))) + offset++; + while (!(mask & 1)) + mask >>= 1; + if (mask & 0xff00) + return -EINVAL; + + *delta_start = index_start * 8 + offset; + *delta_mask = mask; + + return 0; +} + static void *mlxsw_sp_acl_erp_delta_create(void *priv, void *parent_obj, void *obj) { - return NULL; + struct mlxsw_sp_acl_erp_key *parent_key = parent_obj; + struct mlxsw_sp_acl_erp_mask_delta *delta; + struct mlxsw_sp_acl_erp_key *key = obj; + u16 delta_start; + u8 delta_mask; + int err; + + if (parent_key->ctcam || key->ctcam) + return ERR_PTR(-EINVAL); + err = mlxsw_sp_acl_erp_delta_get(parent_key, obj, + &delta_start, &delta_mask); + if (err) + return ERR_PTR(-EINVAL); + + delta = kzalloc(sizeof(*delta), GFP_KERNEL); + if (!delta) + return ERR_PTR(-ENOMEM); + delta->start = delta_start; + delta->mask = delta_mask; + return 0; } static void mlxsw_sp_acl_erp_delta_destroy(void *priv, void *delta_priv) { + struct mlxsw_sp_acl_erp_mask_delta *delta = delta_priv; + + kfree(delta); } static void *mlxsw_sp_acl_erp_root_create(void *priv, void *obj) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h index 08b7368ffafd..b904658c9651 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h @@ -213,9 +213,23 @@ void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_erp_mask; +struct mlxsw_sp_acl_erp_mask_delta { + u16 start; + u8 mask; +}; + +static inline u8 +mlxsw_sp_acl_erp_mask_delta_value(const struct mlxsw_sp_acl_erp_mask_delta *delta, + const char *enc_key) +{ + return (enc_key[delta->start / 8] << (delta->start % 8)) & delta->mask; +} + bool mlxsw_sp_acl_erp_mask_is_ctcam(const struct mlxsw_sp_acl_erp_mask *erp_mask); u8 mlxsw_sp_acl_erp_mask_erp_id(const struct mlxsw_sp_acl_erp_mask *erp_mask); +const struct mlxsw_sp_acl_erp_mask_delta * +mlxsw_sp_acl_erp_mask_delta(const struct mlxsw_sp_acl_erp_mask *erp_mask); struct mlxsw_sp_acl_erp_mask * mlxsw_sp_acl_erp_mask_get(struct mlxsw_sp_acl_atcam_region *aregion, const char *mask, bool ctcam);