From patchwork Fri Jul 27 19:10:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Machata X-Patchwork-Id: 10547627 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 EC5B713BB for ; Fri, 27 Jul 2018 19:10:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D91402C472 for ; Fri, 27 Jul 2018 19:10:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D6C302C49B; Fri, 27 Jul 2018 19:10:49 +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=BAD_ENC_HEADER,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 80F532C497 for ; Fri, 27 Jul 2018 19:10:48 +0000 (UTC) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41cdpZ5nhVzF0wM for ; Sat, 28 Jul 2018 05:10:46 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=mellanox.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="eiK0o4rq"; dkim-atps=neutral X-Original-To: linux-mlxsw@lists.ozlabs.org Delivered-To: linux-mlxsw@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mellanox.com (client-ip=40.107.6.57; helo=eur04-db3-obe.outbound.protection.outlook.com; envelope-from=petrm@mellanox.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=mellanox.com Authentication-Results: lists.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="eiK0o4rq"; dkim-atps=neutral Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60057.outbound.protection.outlook.com [40.107.6.57]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41cdpQ4V97zF0yB for ; Sat, 28 Jul 2018 05:10:38 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=kW36O2fdiyzPzXIYfOUv2Gz5iNSyqAKh0laDzQqqM4A=; b=eiK0o4rqSKG9kGDmoke1dUs9bV97daSNMWMwKL9JDb5JWFKQKh6s3VGoez4DpH/EyQIXG1gl6lhMys97+DyI0ApaXyQxYH7t2Lm3PwNZILOFyxJ1Qxmc8ZtWxoTdwQQtBF1dGpGSlI+vqV1c4MTVFB93Wqp3tP5w0H6FChVydNM= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=petrm@mellanox.com; Received: from t540p (78.45.160.211) by VI1PR05MB4192.eurprd05.prod.outlook.com (2603:10a6:803:4e::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.973.21; Fri, 27 Jul 2018 19:10:33 +0000 From: Petr Machata To: Subject: [PATCH net-next mlxsw v3 07/10] mlxsw: spectrum: Support ieee_setapp, ieee_delapp In-Reply-To: References: Message-Id: Date: Fri, 27 Jul 2018 21:10:29 +0200 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 X-Originating-IP: [78.45.160.211] X-ClientProxiedBy: VI1P189CA0002.EURP189.PROD.OUTLOOK.COM (2603:10a6:802:2a::15) To VI1PR05MB4192.eurprd05.prod.outlook.com (2603:10a6:803:4e::18) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 08511cae-9596-455c-e215-08d5f3f4a07e X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989117)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:VI1PR05MB4192; X-Microsoft-Exchange-Diagnostics: 1; VI1PR05MB4192; 3:kaWiG1lwe7zx5pnTXuXhI2FFxT6ppT1jvpIb5DI6THKjpTp7ndBtRrPog8XiG5tbjgPHLCw5HusaM6VkkYXj8rfu0trOvhFlcIBayleAnC8QD4JojnuCaqLdAgGVqbpn33aXGuvMSpfrlu1U5nk46GLxJdfYQ9lXY7uCBb/qOqbHaRVFHhWhv9yqdH13sxt2GaOtY3ot/f6U3/+D36+eE5Pijzsf701pKBPmWWPGi+Pz91VKqS5u4/+OpkDzWBbT; 25:iTd1jE4ixc2iJUNp8y4rJA1LjsFOel+eBxHQTB+PdF0sRLv0hm0oSlCr09khEEgqQpyPlnwYgZbonfsS69rNPkTEhaXN8T2YR24ADMa2muOOsO1XqKgJDq4nih9RJXYlLrW3Ko+AHuGGsXbY3rGTWZUl350pKKONycvxuV5EWvw0hYTxzWb6DYnK73+6/7/Ni5a5btN00zNBDQHS/H3v8XAvAEP95XcYsNSmjKxnOpwVaBqRB7huI/uSFZkjmMfeO99nYsOkxCTrY5iuMQjnC8wfI5PtleuC6BGPK+hBCO+wOuAhJ8rMi85aSs0OSjEGoJSF25B3msuE6UWS4gqeoQ==; 31:p3obRCeKxobWYaJVNMko7a1utM96N4begNLcuRz011a0e8nAmdz2EhyVC+dNKvJ+Re8Ml/bql7PATGyqLlgBLLf29oWzMdItDfYCymGFMtyPtOBZUCRT14Rsqtsf9dO7DGjhZiXXEi2thYCd1JzdSYwEfm4/2fk/dFEGcH86k649xibpOuF+M9x5KMocRnnaqeys6Xlgci21VT9yBXbhQe3TMhTmu1kanwHY9XgNKUc= X-MS-TrafficTypeDiagnostic: VI1PR05MB4192: X-Microsoft-Exchange-Diagnostics: 1; VI1PR05MB4192; 20:x+4tSzI2ETcgbfmIWfzVYpjb+NL4+Rl9V4qjK6bAExYTa/JjZIMOz+ejpO0gRwSpeMg+k2C9zfNRSJjbbsYv+R+lBUzSLkVQiiGmNfhhzOvgp2bgsspbXGRMr+NR8XXQQHijbViNGnigutYAhELRhrFEtKog5YZDH10rFtlO1el2gY6PGALNixNQPObofQvLEQe53FW/s+NwLwfRWClpBRYy/5Cp0m+ypTuKeskgr4AgmRYPIkrnzTpfYVTmf2ZX5pFoBeigJZOOdFUKQSq1xXlgHkjBe2ZDgdDJwFzsMF1NcUO1FkPGYmf8LZ8xmTXXx4CrDHyLT3UCv5OWdv96olWekfox9ry/UECD9H2t4MIOUb6k3m/1tNzfLy2w2+Q5GDbayhLvkdOgwgerauHcXHgL5ZZWyED8KozAvAKAPaL0fSnIDLC80l4lOjm3N3inPOoYW9f2r16ZDB/UWn4z7AC+DbPeUWzqxaiKnPQugoxdTfN13xnjXFl1/E04Udal; 4:G4V3TKPYKfaEYOW9txbFtzD3FHyWwUHHd8ongAOXxqYWcEVoF2ZCyOma1QmvNUE4VUgHrNzjAiefLK3D8XMWTH1O/HyhhSBBaXhz0t2abykPApDXZhxu6ALTBWrwsE5KMB9blANmJuwi9y4fZzM2n2/dH9ztNJM4NadViqbqomdsYAL+kN4yKDCAr220V3eiZl3ObzXlw18U8tlQYEduZ5eXJB5Evi09ydFX9E3IHfn2qkpiOH7A+q4twnGQrnme74C0G9L9G+xIQ2aEG9dobQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(93006095)(93001095)(3002001)(3231311)(944501410)(52105095)(10201501046)(6055026)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123564045)(20161123560045)(20161123562045)(6072148)(201708071742011)(7699016); SRVR:VI1PR05MB4192; BCL:0; PCL:0; RULEID:; SRVR:VI1PR05MB4192; X-Forefront-PRVS: 07467C4D33 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(396003)(346002)(136003)(366004)(376002)(39860400002)(189003)(199004)(6862004)(105586002)(316002)(66066001)(2616005)(14444005)(52116002)(118296001)(106356001)(47776003)(2351001)(51416003)(478600001)(186003)(486006)(956004)(476003)(11346002)(386003)(53936002)(25786009)(16526019)(446003)(97736004)(6666003)(8936002)(6496006)(81166006)(6486002)(81156014)(76176011)(6636002)(8676002)(48376002)(37006003)(50466002)(36756003)(16586007)(86362001)(58126008)(68736007)(26005)(305945005)(6116002)(5660300001)(3846002)(7736002)(2906002); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR05MB4192; H:t540p; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; VI1PR05MB4192; 23:GCuAUUB8/3VqPTjPAZHK/UXYRF7tJzG5A4ZUBxHgA?= 0IFMGhdzVhQFrqmQaa4oM+xstB5dl2ppe5v+kzLLCUm9+a+wW72ZGYK0bU7UJOQPn2R5Mo7w9el/I3nO2/OvRjRaK35WRNfXD2xLOJCvWoQ6QAktfHrxhhoCG39IiR2Qm2tSbECoAXIz7wofuFIT5gAXrrGN6WYeGt2wu2/fcjJaklRkhizqiy3fBXCu2Jb+S8gPciX9hUPnDODN1xoDQo+r70S47hx+VimsRAA0Qjbpt7lioo666frxcdSE7LiCYePVqWrSQGDm/cBmdsmDmYvEgHjtFFm6dnnySMw1ysWTDLv3xf5mGli75AZ4/Ae5az0nh6a4pjvw1w0weWZjJIJ8onGmRyInGNIi1FdFas8hGSDD4L4oFvMftxgyCTgSONU1yo8e6V4HvIVdIL1XfR95oIpmSucJDgqOAbWfMuyaFqGRNkJblhzmw7e1uRfxCURLRAEfs8zYsGaqG2sP48mc4Fr4A940zzlnwUeYtJW9dH/Ov5m51zrqeM0M3xsl4jwgs2PPXHH6dI9yBHRAkfMSxgkqbLlv7yS/hqU3N/1hh7bIrsK+p9dqBjXbMozXbPgj417uQZBpVlPVUIbH1qricDdiENtYPeSV83nfOk83uxj1kVU1orP64KS1pFLnwv1uP41lKmUJf8E1Ur1yWGEhsxXZYQsQd2fLG6kg6faUEc8mS4WgwhQH6NRyn1BOQorryHdl0Rc02rVSAJI29P2ebZK9AcWCZTvunr1CtTJkgdCiRvwc+eRoYG1qLNZ3lPiTtfd/+r3lItW8JyoMajYEYhKTljGHdyC0kTZLq7dqRGwuqtQ3fa07L8sa7N2JbWSzXRvPD6HIjE05VkvEIjZPYOredleD3VZDAW7Ay1w8gs8FgAdPimWyU3pr02WFAYTvuA5BoDlmljI/R0ai57BIGQlD2+A4zFuk5C8+879tO5fcx6Hrvg5Z5ifyJ/6K+IaWqktJHX1v2+9p1Wqo+wP/rsra3HQvjW0IXdBNwd7NT3j4hOwHKf1PaH4FmReJ75Y2/mKUxk6lUa8xW67cxO8OlPz4+n92CZ7KSMJZOlQMQ28o7sHrIbhZM1OQcpDQI7ypjDMmZgEwChmHkalqzWd2EyNHyCMZ+GrSKWGUvV2+0QCJA9Bl4ihS3H5XEEBsktONFtYoqIGn0K8bsu5JZxDnBhwyrpQFzq/ycOiWYX6gQ== X-Microsoft-Antispam-Message-Info: BiMoZU0lUW2XBPj8l405T45nAQSm/BoYZXSmx/dWYchdocfJPsWrHnDGXGveG9HrG+FHEF6bNsbHanzdj9GuQK4TS55U/Sv5qSx0BJdxNj3UVq4r2tK/2192F2xnfKAmBod4+8m19aqm+IINvYsIIOHqpMrCeCcxdRsrHnrBdaOpJ/QaJNzFDWaTuzLExpL/9d4xbgkvtZTT2MicnE0iRDK119tiMP7LoQvEJUd1aIsg+uQhswHOHZq6lqcF4Cdq7ZuGv4OTje3PCD0ThwiazjnbTyCBoC/moJWlHOIQ0twQ0zyqkP2q5asubZ3G3OkETIr/cN2orChnk/1mZO/0as2Cfk3o6rqEr762sxZWosM= X-Microsoft-Exchange-Diagnostics: 1; VI1PR05MB4192; 6:rN9nYNYP7mTl6tOEfVZMZdWvmTjFoPPjZWlhKbLnNjDpB0D1VeZIw5Btz9gSZY+DVBpdHoKeIuHmCljyorgHJTNN/QB1eR+XWFMVsAH30ufcs2hROZhepdzNQ36dgP3HYuRrBLkEE91OQQBZn+1ta51H4UzAJ+7jgUpf1T47Sb5rXzO2Z2Ws2Mn8GHBKmOTBjSlnIgPaOlO7QTswbzCBUbvV1BHZkl0z4UognAL8o5+2h/kjYBHgBnbM+Gh4w1IdksxfsmClGPQbMpD+4mN4g7pEPp5J4o+sllzV/vJmYk/wEyfhlHxbhuoWkAfEqUACYg+asR31mYno8f663TGSkNogZjva2Uk50uHVzNNg7S7loF6Tu87TEF1+vK68nmcMkT4VPUv0odU27hAd1Eb4SYj4KpVlU2HD6fKCTLQCoVmtpFgrkdhc/IdjdSfRHYcGKz1ip6xysxaF/KtWbWlTnw==; 5:tuJ13bZg12jtIGW0eD52fes0A+AT8VkmDxaDHxjYU0gnJv3XNNR53HrW2C7Z7fp92BCkpJU5DxDZHLdJgtMWfQfT/KBe1CzckPtHbQ2HqI5yFTqwWvBBn3MOFte7HAGq9l7DdNMsapOSWf2NJUrNY4a2sS1CBemeHzY/Qv9uB30=; 7:yr9kDKgU3u3kraU6tHJ8cNHzuAGdvR88CIjv3Sw7ZRJSTWGZwCMDID5yItKkAZqrv7pYph8o6ncppgaHplOxaeQZLEvGDlY6vGJz88zY2ANja5FaNX9KYEQpP7/G6/6RBF7848xveqL7Q39aEe/LBF7cWL4hzqGcZuteInyckfVYeu+ALz42U4wcbRS1URZFSmPJ+8fijfri8/aThwo34QqoKcPJYLPC+6MTysWsf6OUJNMeCqQBeWyul00o3I5Z SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jul 2018 19:10:33.2095 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 08511cae-9596-455c-e215-08d5f3f4a07e X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR05MB4192 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: , Errors-To: linux-mlxsw-bounces+patchwork-linux-mlxsw=patchwork.kernel.org@lists.ozlabs.org X-Virus-Scanned: ClamAV using ClamSMTP The APP TLVs are used for communicating priority-to-protocol ID maps for a given netdevice. Support the following APP TLVs: - DSCP (selector 5) to configure priority-to-DSCP code point maps. Use these maps to configure packet priority on ingress, and DSCP code point rewrite on egress. - Default priority (selector 1, PID 0) to configure priority for the DSCP code points that don't have one assigned by the DSCP selector. In future this could also be used for assigning default port priority when a packet arrives without DSCP tagging. Besides setting up the maps themselves, also configure port trust level and rewrite bits. Port trust level determines whether, for a packet arriving through a certain port, the priority should be determined based on PCP or DSCP header fields. So far, mlxsw kept the device default of trust-PCP. Now, as soon as the first DSCP APP TLV is configured, switch to trust-DSCP. Only when all DSCP APP TLVs are removed, switch back to trust-PCP again. Note that the default priority APP TLV doesn't impact the trust level configuration. Rewrite bits determine whether DSCP and PCP fields of egressing packets should be updated according to switch priority. When port trust is switched to DSCP, enable rewrite of DSCP field. Signed-off-by: Petr Machata Reviewed-by: Ido Schimmel --- drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 4 +- drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c | 269 ++++++++++++++++++++- 2 files changed, 271 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index bc2704193666..13eca1a79d52 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -1,6 +1,6 @@ /* * drivers/net/ethernet/mellanox/mlxsw/spectrum.h - * Copyright (c) 2015-2017 Mellanox Technologies. All rights reserved. + * Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved. * Copyright (c) 2015-2017 Jiri Pirko * Copyright (c) 2015 Ido Schimmel * Copyright (c) 2015 Elad Raz @@ -54,6 +54,7 @@ #include "core.h" #include "core_acl_flex_keys.h" #include "core_acl_flex_actions.h" +#include "reg.h" #define MLXSW_SP_FID_8021D_MAX 1024 @@ -243,6 +244,7 @@ struct mlxsw_sp_port { struct ieee_ets *ets; struct ieee_maxrate *maxrate; struct ieee_pfc *pfc; + enum mlxsw_reg_qpts_trust_state trust_state; } dcb; struct { u8 module; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c index b6ed7f7c531e..c31aeb25ab5a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c @@ -1,6 +1,6 @@ /* * drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c - * Copyright (c) 2016 Mellanox Technologies. All rights reserved. + * Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved. * Copyright (c) 2016 Ido Schimmel * * Redistribution and use in source and binary forms, with or without @@ -255,6 +255,270 @@ static int mlxsw_sp_dcbnl_ieee_setets(struct net_device *dev, return 0; } +static int mlxsw_sp_dcbnl_app_validate(struct net_device *dev, + struct dcb_app *app) +{ + int prio; + + if (app->priority >= IEEE_8021QAZ_MAX_TCS) { + netdev_err(dev, "APP entry with priority value %u is invalid\n", + app->priority); + return -EINVAL; + } + + switch (app->selector) { + case IEEE_8021QAZ_APP_SEL_DSCP: + if (app->protocol >= 64) { + netdev_err(dev, "DSCP APP entry with protocol value %u is invalid\n", + app->protocol); + return -EINVAL; + } + + /* Warn about any DSCP APP entries with the same PID. */ + prio = fls(dcb_ieee_getapp_mask(dev, app)); + if (prio--) { + if (prio < app->priority) + netdev_warn(dev, "Choosing priority %d for DSCP %d in favor of previously-active value of %d\n", + app->priority, app->protocol, prio); + else if (prio > app->priority) + netdev_warn(dev, "Ignoring new priority %d for DSCP %d in favor of current value of %d\n", + app->priority, app->protocol, prio); + } + break; + + case IEEE_8021QAZ_APP_SEL_ETHERTYPE: + if (app->protocol) { + netdev_err(dev, "EtherType APP entries with protocol value != 0 not supported\n"); + return -EINVAL; + } + break; + + default: + netdev_err(dev, "APP entries with selector %u not supported\n", + app->selector); + return -EINVAL; + } + + return 0; +} + +static u8 +mlxsw_sp_port_dcb_app_default_prio(struct mlxsw_sp_port *mlxsw_sp_port) +{ + u8 prio_mask; + + prio_mask = dcb_ieee_getapp_default_prio_mask(mlxsw_sp_port->dev); + if (prio_mask) + /* Take the highest configured priority. */ + return fls(prio_mask) - 1; + + return 0; +} + +static void +mlxsw_sp_port_dcb_app_dscp_prio_map(struct mlxsw_sp_port *mlxsw_sp_port, + u8 default_prio, + struct dcb_ieee_app_dscp_map *map) +{ + int i; + + dcb_ieee_getapp_dscp_prio_mask_map(mlxsw_sp_port->dev, map); + for (i = 0; i < ARRAY_SIZE(map->map); ++i) { + if (map->map[i]) + map->map[i] = fls(map->map[i]) - 1; + else + map->map[i] = default_prio; + } +} + +static bool +mlxsw_sp_port_dcb_app_prio_dscp_map(struct mlxsw_sp_port *mlxsw_sp_port, + struct dcb_ieee_app_prio_map *map) +{ + bool have_dscp = false; + int i; + + dcb_ieee_getapp_prio_dscp_mask_map(mlxsw_sp_port->dev, map); + for (i = 0; i < ARRAY_SIZE(map->map); ++i) { + if (map->map[i]) { + map->map[i] = fls64(map->map[i]) - 1; + have_dscp = true; + } + } + + return have_dscp; +} + +static int +mlxsw_sp_port_dcb_app_update_qpts(struct mlxsw_sp_port *mlxsw_sp_port, + enum mlxsw_reg_qpts_trust_state ts) +{ + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + char qpts_pl[MLXSW_REG_QPTS_LEN]; + + mlxsw_reg_qpts_pack(qpts_pl, mlxsw_sp_port->local_port, ts); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpts), qpts_pl); +} + +static int +mlxsw_sp_port_dcb_app_update_qrwe(struct mlxsw_sp_port *mlxsw_sp_port, + bool rewrite_dscp) +{ + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + char qrwe_pl[MLXSW_REG_QRWE_LEN]; + + mlxsw_reg_qrwe_pack(qrwe_pl, mlxsw_sp_port->local_port, + false, rewrite_dscp); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qrwe), qrwe_pl); +} + +static int +mlxsw_sp_port_dcb_toggle_trust(struct mlxsw_sp_port *mlxsw_sp_port, + enum mlxsw_reg_qpts_trust_state ts) +{ + bool rewrite_dscp = ts == MLXSW_REG_QPTS_TRUST_STATE_DSCP; + int err; + + if (mlxsw_sp_port->dcb.trust_state == ts) + return 0; + + err = mlxsw_sp_port_dcb_app_update_qpts(mlxsw_sp_port, ts); + if (err) + return err; + + err = mlxsw_sp_port_dcb_app_update_qrwe(mlxsw_sp_port, rewrite_dscp); + if (err) + goto err_update_qrwe; + + mlxsw_sp_port->dcb.trust_state = ts; + return 0; + +err_update_qrwe: + mlxsw_sp_port_dcb_app_update_qpts(mlxsw_sp_port, + mlxsw_sp_port->dcb.trust_state); + return err; +} + +static int +mlxsw_sp_port_dcb_app_update_qpdpm(struct mlxsw_sp_port *mlxsw_sp_port, + struct dcb_ieee_app_dscp_map *map) +{ + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + char qpdpm_pl[MLXSW_REG_QPDPM_LEN]; + short int i; + + mlxsw_reg_qpdpm_pack(qpdpm_pl, mlxsw_sp_port->local_port); + for (i = 0; i < ARRAY_SIZE(map->map); ++i) + mlxsw_reg_qpdpm_dscp_pack(qpdpm_pl, i, map->map[i]); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpdpm), qpdpm_pl); +} + +static int +mlxsw_sp_port_dcb_app_update_qpdsm(struct mlxsw_sp_port *mlxsw_sp_port, + struct dcb_ieee_app_prio_map *map) +{ + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + char qpdsm_pl[MLXSW_REG_QPDSM_LEN]; + short int i; + + mlxsw_reg_qpdsm_pack(qpdsm_pl, mlxsw_sp_port->local_port); + for (i = 0; i < ARRAY_SIZE(map->map); ++i) + mlxsw_reg_qpdsm_prio_pack(qpdsm_pl, i, map->map[i]); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpdsm), qpdsm_pl); +} + +static int mlxsw_sp_port_dcb_app_update(struct mlxsw_sp_port *mlxsw_sp_port) +{ + struct dcb_ieee_app_prio_map prio_map; + struct dcb_ieee_app_dscp_map dscp_map; + u8 default_prio; + bool have_dscp; + int err; + + default_prio = mlxsw_sp_port_dcb_app_default_prio(mlxsw_sp_port); + have_dscp = mlxsw_sp_port_dcb_app_prio_dscp_map(mlxsw_sp_port, + &prio_map); + + if (!have_dscp) { + err = mlxsw_sp_port_dcb_toggle_trust(mlxsw_sp_port, + MLXSW_REG_QPTS_TRUST_STATE_PCP); + if (err) + netdev_err(mlxsw_sp_port->dev, "Couldn't switch to trust L2\n"); + return err; + } + + mlxsw_sp_port_dcb_app_dscp_prio_map(mlxsw_sp_port, default_prio, + &dscp_map); + err = mlxsw_sp_port_dcb_app_update_qpdpm(mlxsw_sp_port, + &dscp_map); + if (err) { + netdev_err(mlxsw_sp_port->dev, "Couldn't configure priority map\n"); + return err; + } + + err = mlxsw_sp_port_dcb_app_update_qpdsm(mlxsw_sp_port, + &prio_map); + if (err) { + netdev_err(mlxsw_sp_port->dev, "Couldn't configure DSCP rewrite map\n"); + return err; + } + + err = mlxsw_sp_port_dcb_toggle_trust(mlxsw_sp_port, + MLXSW_REG_QPTS_TRUST_STATE_DSCP); + if (err) { + /* A failure to set trust DSCP means that the QPDPM and QPDSM + * maps installed above are not in effect. And since we are here + * attempting to set trust DSCP, we couldn't have attempted to + * switch trust to PCP. Thus no cleanup is necessary. + */ + netdev_err(mlxsw_sp_port->dev, "Couldn't switch to trust L3\n"); + return err; + } + + return 0; +} + +static int mlxsw_sp_dcbnl_ieee_setapp(struct net_device *dev, + struct dcb_app *app) +{ + struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); + int err; + + err = mlxsw_sp_dcbnl_app_validate(dev, app); + if (err) + return err; + + err = dcb_ieee_setapp(dev, app); + if (err) + return err; + + err = mlxsw_sp_port_dcb_app_update(mlxsw_sp_port); + if (err) + goto err_update; + + return 0; + +err_update: + dcb_ieee_delapp(dev, app); + return err; +} + +static int mlxsw_sp_dcbnl_ieee_delapp(struct net_device *dev, + struct dcb_app *app) +{ + struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); + int err; + + err = dcb_ieee_delapp(dev, app); + if (err) + return err; + + err = mlxsw_sp_port_dcb_app_update(mlxsw_sp_port); + if (err) + netdev_err(dev, "Failed to update DCB APP configuration\n"); + return 0; +} + static int mlxsw_sp_dcbnl_ieee_getmaxrate(struct net_device *dev, struct ieee_maxrate *maxrate) { @@ -394,6 +658,8 @@ static const struct dcbnl_rtnl_ops mlxsw_sp_dcbnl_ops = { .ieee_setmaxrate = mlxsw_sp_dcbnl_ieee_setmaxrate, .ieee_getpfc = mlxsw_sp_dcbnl_ieee_getpfc, .ieee_setpfc = mlxsw_sp_dcbnl_ieee_setpfc, + .ieee_setapp = mlxsw_sp_dcbnl_ieee_setapp, + .ieee_delapp = mlxsw_sp_dcbnl_ieee_delapp, .getdcbx = mlxsw_sp_dcbnl_getdcbx, .setdcbx = mlxsw_sp_dcbnl_setdcbx, @@ -467,6 +733,7 @@ int mlxsw_sp_port_dcb_init(struct mlxsw_sp_port *mlxsw_sp_port) if (err) goto err_port_pfc_init; + mlxsw_sp_port->dcb.trust_state = MLXSW_REG_QPTS_TRUST_STATE_PCP; mlxsw_sp_port->dev->dcbnl_ops = &mlxsw_sp_dcbnl_ops; return 0;