From patchwork Thu Jun 10 23:26:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 459018 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A764CC48BD1 for ; Thu, 10 Jun 2021 23:27:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8B8E0613E9 for ; Thu, 10 Jun 2021 23:27:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230504AbhFJX3A (ORCPT ); Thu, 10 Jun 2021 19:29:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51950 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230001AbhFJX26 (ORCPT ); Thu, 10 Jun 2021 19:28:58 -0400 Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 766A6C061574 for ; Thu, 10 Jun 2021 16:26:45 -0700 (PDT) Received: by mail-ej1-x62e.google.com with SMTP id ci15so1629427ejc.10 for ; Thu, 10 Jun 2021 16:26:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=aszyaYZsJcZYQj2Xj4LwuEfwn7jbhFlbU+YBkgFvQ3Q=; b=ljavh+DxOM0rbbFw5h/Oa0VEcoODQr8jw9WFrSjY35ePWwW4euYDNf3POa/OL/QBlN Pp+VPDcfn9zChfB4bg57AzyfCaZ/TRUmkuGIR9e4iJ/0q0Ojw4BoG7Q7wZhTPVXj46tG 0r3C4HfMfYx/8/Ohmx/s4PXbFrK3kbzJsucBfXSXGCjuz15kgdRi+RVFfgaOIKRbKKHv AIYCpCxV5MhCp43NYxNkB5xsIIyKOJtnuHoWU3TwDc4IloxQk+ge91V5QkRUIVufZO3p T11OVPRJRidL9Yw6hFCt/2UWdEW4zHxbqTaOn9G4180xJse904dqWGTwp8sfkGFOVvCJ AZ2w== 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:mime-version:content-transfer-encoding; bh=aszyaYZsJcZYQj2Xj4LwuEfwn7jbhFlbU+YBkgFvQ3Q=; b=ClMyFz/6dgmHEnvmXLxnndxJxw1O9KECs8cxHTzbe9n6eOTEtW/qmxYXo4v+goQ4Il BMh35/E43kmSOn0KKWBQIoK32iNrM9WVtY6tvdn6W3WOSGnshXVX9tDuJw3699aa21Li S6QKvIimrL9qPMXdwBr9zOY8qJP72cJc1hOlrk966JdMiz5+1a2SAHfNdmYI0CT4aGD+ lTbREyGgwO4LXjzsITAc1Kss6pgDYHNGRdFlbWHExLBha0cT++VMO/Oc0t6WqRqMzkW0 fuilEQoNvTRULvHN5jZnNLuYe/xjatr8YQzMBLMx+fV2VuWDVlFPloU12W9qO1SGDh7V QxgA== X-Gm-Message-State: AOAM530YbuifcNQTIggwfPk2Li0z4Vw44MkNEQdobPlzbOROEB8aEwMw eopERuIiIPHjNU6wEUBTxgY= X-Google-Smtp-Source: ABdhPJzso/R7uH5KOSWGjUb0Tj5Ev9EbsOSXyNouOESQug9hPVpHvoSRUO9LZEr9Cz6hJypUo4k3tg== X-Received: by 2002:a17:906:f9d1:: with SMTP id lj17mr781607ejb.345.1623367603982; Thu, 10 Jun 2021 16:26:43 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id j22sm1534187ejt.11.2021.06.10.16.26.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:26:43 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Richard Cochran , Vladimir Oltean Subject: [PATCH v2 net-next 01/10] net: dsa: sja1105: enable the TTEthernet engine on SJA1110 Date: Fri, 11 Jun 2021 02:26:20 +0300 Message-Id: <20210610232629.1948053-2-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610232629.1948053-1-olteanv@gmail.com> References: <20210610232629.1948053-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean As opposed to SJA1105 where there are parts with TTEthernet and parts without, in SJA1110 all parts support it, but it must be enabled in the static config. So enable it unconditionally. We use it for the tc-taprio and tc-gate offload. Signed-off-by: Vladimir Oltean --- v1->v2: none drivers/net/dsa/sja1105/sja1105_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 9881ef134666..86563e6fd85f 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -675,6 +675,8 @@ static int sja1105_init_general_params(struct sja1105_private *priv) */ .tpid = ETH_P_SJA1105, .tpid2 = ETH_P_SJA1105, + /* Enable the TTEthernet engine on SJA1110 */ + .tte_en = true, }; struct dsa_switch *ds = priv->ds; struct sja1105_table *table; From patchwork Thu Jun 10 23:26:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 458292 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4AC47C48BD1 for ; Thu, 10 Jun 2021 23:27:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 293C4613B3 for ; Thu, 10 Jun 2021 23:27:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230425AbhFJX25 (ORCPT ); Thu, 10 Jun 2021 19:28:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51954 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230001AbhFJX24 (ORCPT ); Thu, 10 Jun 2021 19:28:56 -0400 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C8ECC0617A6 for ; Thu, 10 Jun 2021 16:26:46 -0700 (PDT) Received: by mail-ed1-x530.google.com with SMTP id r11so34992642edt.13 for ; Thu, 10 Jun 2021 16:26:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OZCDcKl+1WwOP0AVAhsZWP5RDajFfbeXgqpQnTG4wPs=; b=c71tk3Z3mBs1oMffG/pTjrcshtngVZoeQ8Byl9l2GWpdO1npj6YJ37JiJkMv4Ob3dl WwLv1uLlTDFEI593n8H9IQRSLfGsC7btQljreLNd6m6vKNY0ZGnxW88H9WSM5s8aeS0i TO70lyI3qB32UhIVMw81/Ryq3cNZeE05mdrLbOjgXdRYFarO5CoEV28AmP0/eT7lop/t 0vjPVhfiwKeNc3KFOWO9yyjoVal3EsrPveDGYscLMuhMUoYfHHXCysV2KnIF7Wb+eNKk Db3+wEhUpcRWuUSsZsA2uPtGmZzB7G28HqluPCVzYjvCm6XnCtugBKxl2IT6s+yBzzij t5Ng== 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:mime-version:content-transfer-encoding; bh=OZCDcKl+1WwOP0AVAhsZWP5RDajFfbeXgqpQnTG4wPs=; b=G/uIB9KaU3F8ZgqcYbOuCs+yYIK3q6s0n0LMlIfckcbK4+TDHvw8WZEerSNm8uYVbE BwpfSKq+SSlM7I7J8KlQF9zicTDZ/h6gDn2lBMcJvYw93LNf7DNhvcYricX5YxQU1gBq pdaOSjMCLNezMi1w+kqbiaty3SLoPD5xH0F/9dFQDd2SdfjkrSSyR0WUsMkFg3bkYASZ gHbujMWJ5WtlqHhIJkYCI38Um4U49u2xdY6jOvTnuDhqqzHxQTzcvl0dLRKnQ5cHD8+8 s26spr0bsUbPlCA38FwL9G723zZ0m7+ISfEz4kVkwxDQePcDH3qqijs4WovSuc70wgwZ 4ewA== X-Gm-Message-State: AOAM533EhzLVtaVIlMnkuLAt7M0negDS3LUvaU8e+RndplBpxutoMT8l sSq6vEWRukMVGBaU1sjLASw= X-Google-Smtp-Source: ABdhPJzTOa7PHM15lS7g7lSWwJL3TvZkdtdaCo4f+C2v+Mfio4cA1vHNKNzva7e0S4c+/sZ3xVcSEw== X-Received: by 2002:aa7:c68f:: with SMTP id n15mr825372edq.145.1623367604902; Thu, 10 Jun 2021 16:26:44 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id j22sm1534187ejt.11.2021.06.10.16.26.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:26:44 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Richard Cochran , Vladimir Oltean Subject: [PATCH v2 net-next 02/10] net: dsa: sja1105: allow RX timestamps to be taken on all ports for SJA1110 Date: Fri, 11 Jun 2021 02:26:21 +0300 Message-Id: <20210610232629.1948053-3-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610232629.1948053-1-olteanv@gmail.com> References: <20210610232629.1948053-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean On SJA1105, there is support for a cascade port which is presumably connected to a downstream SJA1105 switch. The upstream one does not take PTP timestamps for packets received on this port, presumably because the downstream switch already did (and for PTP, it only makes sense for the leaf nodes in a DSA switch tree to do that). I haven't been able to validate that feature in a fully assembled setup, so I am disabling the feature by setting the cascade port to an unused port value (ds->num_ports). In SJA1110, multiple cascade ports are supported, and CASC_PORT became a bit mask from a port number. So when CASC_PORT is set to ds->num_ports (which is 11 on SJA1110), it is actually set to 0b1011, so ports 3, 1 and 0 are configured as cascade ports and we cannot take RX timestamps on them. So we need to introduce a check for SJA1110 and set things differently (to zero there), so that the cascading feature is properly disabled and RX timestamps can be taken on all ports. Signed-off-by: Vladimir Oltean --- v1->v2: none drivers/net/dsa/sja1105/sja1105.h | 1 + drivers/net/dsa/sja1105/sja1105_main.c | 27 ++++++++++++++++---------- drivers/net/dsa/sja1105/sja1105_spi.c | 4 ++++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 03750e9f5a4e..cd45e9558425 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -110,6 +110,7 @@ struct sja1105_info { int num_cbs_shapers; int max_frame_mem; int num_ports; + bool multiple_cascade_ports; const struct sja1105_dynamic_table_ops *dyn_ops; const struct sja1105_table_ops *static_ops; const struct sja1105_regs *regs; diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 86563e6fd85f..4e73a4abb09a 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -656,14 +656,6 @@ static int sja1105_init_general_params(struct sja1105_private *priv) .host_port = priv->ds->num_ports, /* Default to an invalid value */ .mirr_port = priv->ds->num_ports, - /* Link-local traffic received on casc_port will be forwarded - * to host_port without embedding the source port and device ID - * info in the destination MAC address (presumably because it - * is a cascaded port and a downstream SJA switch already did - * that). Default to an invalid port (to disable the feature) - * and overwrite this if we find any DSA (cascaded) ports. - */ - .casc_port = priv->ds->num_ports, /* No TTEthernet */ .vllupformat = SJA1105_VL_FORMAT_PSFP, .vlmarker = 0, @@ -678,6 +670,7 @@ static int sja1105_init_general_params(struct sja1105_private *priv) /* Enable the TTEthernet engine on SJA1110 */ .tte_en = true, }; + struct sja1105_general_params_entry *general_params; struct dsa_switch *ds = priv->ds; struct sja1105_table *table; int port; @@ -703,12 +696,26 @@ static int sja1105_init_general_params(struct sja1105_private *priv) table->entry_count = table->ops->max_entry_count; + general_params = table->entries; + /* This table only has a single entry */ - ((struct sja1105_general_params_entry *)table->entries)[0] = - default_general_params; + general_params[0] = default_general_params; sja1110_select_tdmaconfigidx(priv); + /* Link-local traffic received on casc_port will be forwarded + * to host_port without embedding the source port and device ID + * info in the destination MAC address, and no RX timestamps will be + * taken either (presumably because it is a cascaded port and a + * downstream SJA switch already did that). + * To disable the feature, we need to do different things depending on + * switch generation. On SJA1105 we need to set an invalid port, while + * on SJA1110 which support multiple cascaded ports, this field is a + * bitmask so it must be left zero. + */ + if (!priv->info->multiple_cascade_ports) + general_params->casc_port = ds->num_ports; + return 0; } diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 53c2213660a3..1eae25007167 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -770,6 +770,7 @@ const struct sja1105_info sja1110a_info = { .regs = &sja1110_regs, .qinq_tpid = ETH_P_8021AD, .can_limit_mcast_flood = true, + .multiple_cascade_ports = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, @@ -817,6 +818,7 @@ const struct sja1105_info sja1110b_info = { .regs = &sja1110_regs, .qinq_tpid = ETH_P_8021AD, .can_limit_mcast_flood = true, + .multiple_cascade_ports = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, @@ -864,6 +866,7 @@ const struct sja1105_info sja1110c_info = { .regs = &sja1110_regs, .qinq_tpid = ETH_P_8021AD, .can_limit_mcast_flood = true, + .multiple_cascade_ports = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, @@ -911,6 +914,7 @@ const struct sja1105_info sja1110d_info = { .regs = &sja1110_regs, .qinq_tpid = ETH_P_8021AD, .can_limit_mcast_flood = true, + .multiple_cascade_ports = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, From patchwork Thu Jun 10 23:26:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 458290 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 610A0C48BD1 for ; Thu, 10 Jun 2021 23:27:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3D7F6613E9 for ; Thu, 10 Jun 2021 23:27:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231197AbhFJX3o (ORCPT ); Thu, 10 Jun 2021 19:29:44 -0400 Received: from mail-ej1-f49.google.com ([209.85.218.49]:46599 "EHLO mail-ej1-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230212AbhFJX3n (ORCPT ); Thu, 10 Jun 2021 19:29:43 -0400 Received: by mail-ej1-f49.google.com with SMTP id he7so1604345ejc.13 for ; Thu, 10 Jun 2021 16:27:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Mf8szwaTKwQ8Rx3/ccDfT1vgN+QQn7FLLnZd/OFjPj8=; b=PRVOS9vukCh7PlmtLMtEYqJIEkmmztu79np0BfwKYKHKtc5g3HE1GEeTobIQY+/fwI 7RyFHMkgPDi/b6j/k7+NS9Q4uPInAbfRt8gc8UtKLdTa7HdXRfJeKeNG4AUb8yeOvLRF +qp6ZCvbD12gqJatsNrfDze+Dho2jl8AdFpmx7/xrF/IPGqxFY1bW5p7ALWXVaBUyqwi mEl1WXyhAMnwAqpnyh+ourM/+4rLMUNhW7ljwP0ChNyaZjt1QOqQ9q2ehGVv8FjNXVCb SZsaZA4wGY1+Zg5mn1iGX6mSxgTZll7JXR9VT3Ypk+VRRbSsnwo1KPm63t0fgrfiEHQj u95A== 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:mime-version:content-transfer-encoding; bh=Mf8szwaTKwQ8Rx3/ccDfT1vgN+QQn7FLLnZd/OFjPj8=; b=b4IqViq13sYraFawGIko//DCQxtuQCAx4fTz2t32aDGGxgFsimnfSzwJwki+X0WckY UQ2ib65YtZAfiz2wxLGGzdJ8NoThRnjs4V7rkhrkdfrCefB51tlBQsXckW0TZ6x8lRl7 qMLuqaCBR4pMhGKGu7e6EFPiyAAp8JgPnrd0fNDvOgwiOsm1crAwkxWNRdbKDvY4jvBf K2ZGuT5Nn4wcsY6Pn2f7BRYtqqx5T3KVyChip0hwqCZRwNSLQTRbeLWlm8XO9gHvDYsR ZC8EfvFOuzmARVTr8BL/BSLXNcaRmyxHCVtQ/HC+/6+cI5IvCs3Nmr2bLBdr/A7s/91l aXDw== X-Gm-Message-State: AOAM5329nVAd4fvPKD9E0zPjVtClHVJ8VauJaMutG7QwiXSokLwSP9rZ 0EN+wa5ytEHEE0SBGg3ug/o= X-Google-Smtp-Source: ABdhPJxMGSfzpC6kXex3gV4VGL1httqQsoTYvP0BQMu8D+9o2tDo6bA8wAYZYKmTYinqVULmurQtdg== X-Received: by 2002:a17:906:c00f:: with SMTP id e15mr841619ejz.458.1623367605866; Thu, 10 Jun 2021 16:26:45 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id j22sm1534187ejt.11.2021.06.10.16.26.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:26:45 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Richard Cochran , Vladimir Oltean Subject: [PATCH v2 net-next 03/10] net: dsa: generalize overhead for taggers that use both headers and trailers Date: Fri, 11 Jun 2021 02:26:22 +0300 Message-Id: <20210610232629.1948053-4-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610232629.1948053-1-olteanv@gmail.com> References: <20210610232629.1948053-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean Some really really weird switches just couldn't decide whether to use a normal or a tail tagger, so they just did both. This creates problems for DSA, because we only have the concept of an 'overhead' which can be applied to the headroom or to the tailroom of the skb (like for example during the central TX reallocation procedure), depending on the value of bool tail_tag, but not to both. We need to generalize DSA to cater for these odd switches by transforming the 'overhead / tail_tag' pair into 'needed_headroom / needed_tailroom'. The DSA master's MTU is increased to account for both. The flow dissector code is modified such that it only calls the DSA adjustment callback if the tagger has a non-zero header length. Taggers are trivially modified to declare either needed_headroom or needed_tailroom, based on the tail_tag value that they currently declare. Signed-off-by: Vladimir Oltean --- v1->v2: none Documentation/networking/dsa/dsa.rst | 21 +++++++++++---------- include/net/dsa.h | 6 +++--- net/core/flow_dissector.c | 2 +- net/dsa/dsa_priv.h | 5 +++++ net/dsa/master.c | 6 ++++-- net/dsa/slave.c | 10 ++++------ net/dsa/tag_ar9331.c | 2 +- net/dsa/tag_brcm.c | 6 +++--- net/dsa/tag_dsa.c | 4 ++-- net/dsa/tag_gswip.c | 2 +- net/dsa/tag_hellcreek.c | 3 +-- net/dsa/tag_ksz.c | 9 +++------ net/dsa/tag_lan9303.c | 2 +- net/dsa/tag_mtk.c | 2 +- net/dsa/tag_ocelot.c | 4 ++-- net/dsa/tag_ocelot_8021q.c | 2 +- net/dsa/tag_qca.c | 2 +- net/dsa/tag_rtl4_a.c | 2 +- net/dsa/tag_sja1105.c | 2 +- net/dsa/tag_trailer.c | 3 +-- net/dsa/tag_xrs700x.c | 3 +-- 21 files changed, 49 insertions(+), 49 deletions(-) diff --git a/Documentation/networking/dsa/dsa.rst b/Documentation/networking/dsa/dsa.rst index 8688009514cc..20baacf2bc5c 100644 --- a/Documentation/networking/dsa/dsa.rst +++ b/Documentation/networking/dsa/dsa.rst @@ -93,14 +93,15 @@ A tagging protocol may tag all packets with switch tags of the same length, or the tag length might vary (for example packets with PTP timestamps might require an extended switch tag, or there might be one tag length on TX and a different one on RX). Either way, the tagging protocol driver must populate the -``struct dsa_device_ops::overhead`` with the length in octets of the longest -switch frame header. The DSA framework will automatically adjust the MTU of the -master interface to accomodate for this extra size in order for DSA user ports -to support the standard MTU (L2 payload length) of 1500 octets. The ``overhead`` -is also used to request from the network stack, on a best-effort basis, the -allocation of packets with a ``needed_headroom`` or ``needed_tailroom`` -sufficient such that the act of pushing the switch tag on transmission of a -packet does not cause it to reallocate due to lack of memory. +``struct dsa_device_ops::needed_headroom`` and/or ``struct dsa_device_ops::needed_tailroom`` +with the length in octets of the longest switch frame header/trailer. The DSA +framework will automatically adjust the MTU of the master interface to +accommodate for this extra size in order for DSA user ports to support the +standard MTU (L2 payload length) of 1500 octets. The ``needed_headroom`` and +``needed_tailroom`` properties are also used to request from the network stack, +on a best-effort basis, the allocation of packets with enough extra space such +that the act of pushing the switch tag on transmission of a packet does not +cause it to reallocate due to lack of memory. Even though applications are not expected to parse DSA-specific frame headers, the format on the wire of the tagging protocol represents an Application Binary @@ -169,8 +170,8 @@ The job of this method is to prepare the skb in a way that the switch will understand what egress port the packet is for (and not deliver it towards other ports). Typically this is fulfilled by pushing a frame header. Checking for insufficient size in the skb headroom or tailroom is unnecessary provided that -the ``overhead`` and ``tail_tag`` properties were filled out properly, because -DSA ensures there is enough space before calling this method. +the ``needed_headroom`` and ``needed_tailroom`` properties were filled out +properly, because DSA ensures there is enough space before calling this method. The reception of a packet goes through the tagger's ``rcv`` function. The passed ``struct sk_buff *skb`` has ``skb->data`` pointing at diff --git a/include/net/dsa.h b/include/net/dsa.h index e1a2610a0e06..0a10f6fffc3d 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -91,7 +91,8 @@ struct dsa_device_ops { * as regular on the master net device. */ bool (*filter)(const struct sk_buff *skb, struct net_device *dev); - unsigned int overhead; + unsigned int needed_headroom; + unsigned int needed_tailroom; const char *name; enum dsa_tag_protocol proto; /* Some tagging protocols either mangle or shift the destination MAC @@ -100,7 +101,6 @@ struct dsa_device_ops { * its RX filter. */ bool promisc_on_master; - bool tail_tag; }; /* This structure defines the control interfaces that are overlayed by the @@ -926,7 +926,7 @@ static inline void dsa_tag_generic_flow_dissect(const struct sk_buff *skb, { #if IS_ENABLED(CONFIG_NET_DSA) const struct dsa_device_ops *ops = skb->dev->dsa_ptr->tag_ops; - int tag_len = ops->overhead; + int tag_len = ops->needed_headroom; *offset = tag_len; *proto = ((__be16 *)skb->data)[(tag_len / 2) - 1]; diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 3ed7c98a98e1..c04455981c1e 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -944,7 +944,7 @@ bool __skb_flow_dissect(const struct net *net, ops = skb->dev->dsa_ptr->tag_ops; /* Tail taggers don't break flow dissection */ - if (!ops->tail_tag) { + if (!ops->needed_headroom) { if (ops->flow_dissect) ops->flow_dissect(skb, &proto, &offset); else diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 92282de54230..b8b17474b72b 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -154,6 +154,11 @@ const struct dsa_device_ops *dsa_find_tagger_by_name(const char *buf); bool dsa_schedule_work(struct work_struct *work); const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops); +static inline int dsa_tag_protocol_overhead(const struct dsa_device_ops *ops) +{ + return ops->needed_headroom + ops->needed_tailroom; +} + /* master.c */ int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp); void dsa_master_teardown(struct net_device *dev); diff --git a/net/dsa/master.c b/net/dsa/master.c index 63adbc21a735..3fc90e36772d 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -346,10 +346,12 @@ static struct lock_class_key dsa_master_addr_list_lock_key; int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp) { - int mtu = ETH_DATA_LEN + cpu_dp->tag_ops->overhead; + const struct dsa_device_ops *tag_ops = cpu_dp->tag_ops; struct dsa_switch *ds = cpu_dp->ds; struct device_link *consumer_link; - int ret; + int mtu, ret; + + mtu = ETH_DATA_LEN + dsa_tag_protocol_overhead(tag_ops); /* The DSA master must use SET_NETDEV_DEV for this to work. */ consumer_link = device_link_add(ds->dev, dev->dev.parent, diff --git a/net/dsa/slave.c b/net/dsa/slave.c index d4756b920108..3ca509eb284d 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1569,7 +1569,7 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu) mtu_limit = min_t(int, master->max_mtu, dev->max_mtu); old_master_mtu = master->mtu; - new_master_mtu = largest_mtu + cpu_dp->tag_ops->overhead; + new_master_mtu = largest_mtu + dsa_tag_protocol_overhead(cpu_dp->tag_ops); if (new_master_mtu > mtu_limit) return -ERANGE; @@ -1605,7 +1605,7 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu) out_port_failed: if (new_master_mtu != old_master_mtu) dsa_port_mtu_change(cpu_dp, old_master_mtu - - cpu_dp->tag_ops->overhead, + dsa_tag_protocol_overhead(cpu_dp->tag_ops), true); out_cpu_failed: if (new_master_mtu != old_master_mtu) @@ -1824,10 +1824,8 @@ void dsa_slave_setup_tagger(struct net_device *slave) const struct dsa_port *cpu_dp = dp->cpu_dp; struct net_device *master = cpu_dp->master; - if (cpu_dp->tag_ops->tail_tag) - slave->needed_tailroom = cpu_dp->tag_ops->overhead; - else - slave->needed_headroom = cpu_dp->tag_ops->overhead; + slave->needed_headroom = cpu_dp->tag_ops->needed_headroom; + slave->needed_tailroom = cpu_dp->tag_ops->needed_tailroom; /* Try to save one extra realloc later in the TX path (in the master) * by also inheriting the master's needed headroom and tailroom. * The 8021q driver also does this. diff --git a/net/dsa/tag_ar9331.c b/net/dsa/tag_ar9331.c index 002cf7f952e2..0efae1a372b3 100644 --- a/net/dsa/tag_ar9331.c +++ b/net/dsa/tag_ar9331.c @@ -85,7 +85,7 @@ static const struct dsa_device_ops ar9331_netdev_ops = { .proto = DSA_TAG_PROTO_AR9331, .xmit = ar9331_tag_xmit, .rcv = ar9331_tag_rcv, - .overhead = AR9331_HDR_LEN, + .needed_headroom = AR9331_HDR_LEN, }; MODULE_LICENSE("GPL v2"); diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index 40e9f3098c8d..0750af951fc9 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -205,7 +205,7 @@ static const struct dsa_device_ops brcm_netdev_ops = { .proto = DSA_TAG_PROTO_BRCM, .xmit = brcm_tag_xmit, .rcv = brcm_tag_rcv, - .overhead = BRCM_TAG_LEN, + .needed_headroom = BRCM_TAG_LEN, }; DSA_TAG_DRIVER(brcm_netdev_ops); @@ -286,7 +286,7 @@ static const struct dsa_device_ops brcm_legacy_netdev_ops = { .proto = DSA_TAG_PROTO_BRCM_LEGACY, .xmit = brcm_leg_tag_xmit, .rcv = brcm_leg_tag_rcv, - .overhead = BRCM_LEG_TAG_LEN, + .needed_headroom = BRCM_LEG_TAG_LEN, }; DSA_TAG_DRIVER(brcm_legacy_netdev_ops); @@ -314,7 +314,7 @@ static const struct dsa_device_ops brcm_prepend_netdev_ops = { .proto = DSA_TAG_PROTO_BRCM_PREPEND, .xmit = brcm_tag_xmit_prepend, .rcv = brcm_tag_rcv_prepend, - .overhead = BRCM_TAG_LEN, + .needed_headroom = BRCM_TAG_LEN, }; DSA_TAG_DRIVER(brcm_prepend_netdev_ops); diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index 7e7b7decdf39..a822355afc90 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -303,7 +303,7 @@ static const struct dsa_device_ops dsa_netdev_ops = { .proto = DSA_TAG_PROTO_DSA, .xmit = dsa_xmit, .rcv = dsa_rcv, - .overhead = DSA_HLEN, + .needed_headroom = DSA_HLEN, }; DSA_TAG_DRIVER(dsa_netdev_ops); @@ -346,7 +346,7 @@ static const struct dsa_device_ops edsa_netdev_ops = { .proto = DSA_TAG_PROTO_EDSA, .xmit = edsa_xmit, .rcv = edsa_rcv, - .overhead = EDSA_HLEN, + .needed_headroom = EDSA_HLEN, }; DSA_TAG_DRIVER(edsa_netdev_ops); diff --git a/net/dsa/tag_gswip.c b/net/dsa/tag_gswip.c index 2f5bd5e338ab..5985dab06ab8 100644 --- a/net/dsa/tag_gswip.c +++ b/net/dsa/tag_gswip.c @@ -103,7 +103,7 @@ static const struct dsa_device_ops gswip_netdev_ops = { .proto = DSA_TAG_PROTO_GSWIP, .xmit = gswip_tag_xmit, .rcv = gswip_tag_rcv, - .overhead = GSWIP_RX_HEADER_LEN, + .needed_headroom = GSWIP_RX_HEADER_LEN, }; MODULE_LICENSE("GPL"); diff --git a/net/dsa/tag_hellcreek.c b/net/dsa/tag_hellcreek.c index a09805c8e1ab..424130f85f59 100644 --- a/net/dsa/tag_hellcreek.c +++ b/net/dsa/tag_hellcreek.c @@ -54,8 +54,7 @@ static const struct dsa_device_ops hellcreek_netdev_ops = { .proto = DSA_TAG_PROTO_HELLCREEK, .xmit = hellcreek_xmit, .rcv = hellcreek_rcv, - .overhead = HELLCREEK_TAG_LEN, - .tail_tag = true, + .needed_tailroom = HELLCREEK_TAG_LEN, }; MODULE_LICENSE("Dual MIT/GPL"); diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c index 4820dbcedfa2..53565f48934c 100644 --- a/net/dsa/tag_ksz.c +++ b/net/dsa/tag_ksz.c @@ -77,8 +77,7 @@ static const struct dsa_device_ops ksz8795_netdev_ops = { .proto = DSA_TAG_PROTO_KSZ8795, .xmit = ksz8795_xmit, .rcv = ksz8795_rcv, - .overhead = KSZ_INGRESS_TAG_LEN, - .tail_tag = true, + .needed_tailroom = KSZ_INGRESS_TAG_LEN, }; DSA_TAG_DRIVER(ksz8795_netdev_ops); @@ -149,8 +148,7 @@ static const struct dsa_device_ops ksz9477_netdev_ops = { .proto = DSA_TAG_PROTO_KSZ9477, .xmit = ksz9477_xmit, .rcv = ksz9477_rcv, - .overhead = KSZ9477_INGRESS_TAG_LEN, - .tail_tag = true, + .needed_tailroom = KSZ9477_INGRESS_TAG_LEN, }; DSA_TAG_DRIVER(ksz9477_netdev_ops); @@ -183,8 +181,7 @@ static const struct dsa_device_ops ksz9893_netdev_ops = { .proto = DSA_TAG_PROTO_KSZ9893, .xmit = ksz9893_xmit, .rcv = ksz9477_rcv, - .overhead = KSZ_INGRESS_TAG_LEN, - .tail_tag = true, + .needed_tailroom = KSZ_INGRESS_TAG_LEN, }; DSA_TAG_DRIVER(ksz9893_netdev_ops); diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c index aa1318dccaf0..26207ef39ebc 100644 --- a/net/dsa/tag_lan9303.c +++ b/net/dsa/tag_lan9303.c @@ -125,7 +125,7 @@ static const struct dsa_device_ops lan9303_netdev_ops = { .proto = DSA_TAG_PROTO_LAN9303, .xmit = lan9303_xmit, .rcv = lan9303_rcv, - .overhead = LAN9303_TAG_LEN, + .needed_headroom = LAN9303_TAG_LEN, }; MODULE_LICENSE("GPL"); diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c index f9b2966d1936..cc3ba864ad5b 100644 --- a/net/dsa/tag_mtk.c +++ b/net/dsa/tag_mtk.c @@ -102,7 +102,7 @@ static const struct dsa_device_ops mtk_netdev_ops = { .proto = DSA_TAG_PROTO_MTK, .xmit = mtk_tag_xmit, .rcv = mtk_tag_rcv, - .overhead = MTK_HDR_LEN, + .needed_headroom = MTK_HDR_LEN, }; MODULE_LICENSE("GPL"); diff --git a/net/dsa/tag_ocelot.c b/net/dsa/tag_ocelot.c index 91f0fd1242cd..190f4bfd3bef 100644 --- a/net/dsa/tag_ocelot.c +++ b/net/dsa/tag_ocelot.c @@ -143,7 +143,7 @@ static const struct dsa_device_ops ocelot_netdev_ops = { .proto = DSA_TAG_PROTO_OCELOT, .xmit = ocelot_xmit, .rcv = ocelot_rcv, - .overhead = OCELOT_TOTAL_TAG_LEN, + .needed_headroom = OCELOT_TOTAL_TAG_LEN, .promisc_on_master = true, }; @@ -155,7 +155,7 @@ static const struct dsa_device_ops seville_netdev_ops = { .proto = DSA_TAG_PROTO_SEVILLE, .xmit = seville_xmit, .rcv = ocelot_rcv, - .overhead = OCELOT_TOTAL_TAG_LEN, + .needed_headroom = OCELOT_TOTAL_TAG_LEN, .promisc_on_master = true, }; diff --git a/net/dsa/tag_ocelot_8021q.c b/net/dsa/tag_ocelot_8021q.c index 62a93303bd63..663b74793cfc 100644 --- a/net/dsa/tag_ocelot_8021q.c +++ b/net/dsa/tag_ocelot_8021q.c @@ -73,7 +73,7 @@ static const struct dsa_device_ops ocelot_8021q_netdev_ops = { .proto = DSA_TAG_PROTO_OCELOT_8021Q, .xmit = ocelot_xmit, .rcv = ocelot_rcv, - .overhead = VLAN_HLEN, + .needed_headroom = VLAN_HLEN, .promisc_on_master = true, }; diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c index 88181b52f480..693bda013065 100644 --- a/net/dsa/tag_qca.c +++ b/net/dsa/tag_qca.c @@ -91,7 +91,7 @@ static const struct dsa_device_ops qca_netdev_ops = { .proto = DSA_TAG_PROTO_QCA, .xmit = qca_tag_xmit, .rcv = qca_tag_rcv, - .overhead = QCA_HDR_LEN, + .needed_headroom = QCA_HDR_LEN, }; MODULE_LICENSE("GPL"); diff --git a/net/dsa/tag_rtl4_a.c b/net/dsa/tag_rtl4_a.c index cf8ac316f4c7..57c46b4ab2b3 100644 --- a/net/dsa/tag_rtl4_a.c +++ b/net/dsa/tag_rtl4_a.c @@ -124,7 +124,7 @@ static const struct dsa_device_ops rtl4a_netdev_ops = { .proto = DSA_TAG_PROTO_RTL4_A, .xmit = rtl4a_tag_xmit, .rcv = rtl4a_tag_rcv, - .overhead = RTL4_A_HDR_LEN, + .needed_headroom = RTL4_A_HDR_LEN, }; module_dsa_tag_driver(rtl4a_netdev_ops); diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c index 50496013cdb7..ff4a81eae16f 100644 --- a/net/dsa/tag_sja1105.c +++ b/net/dsa/tag_sja1105.c @@ -362,7 +362,7 @@ static const struct dsa_device_ops sja1105_netdev_ops = { .xmit = sja1105_xmit, .rcv = sja1105_rcv, .filter = sja1105_filter, - .overhead = VLAN_HLEN, + .needed_headroom = VLAN_HLEN, .flow_dissect = sja1105_flow_dissect, .promisc_on_master = true, }; diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c index 5b97ede56a0f..ba73804340a5 100644 --- a/net/dsa/tag_trailer.c +++ b/net/dsa/tag_trailer.c @@ -55,8 +55,7 @@ static const struct dsa_device_ops trailer_netdev_ops = { .proto = DSA_TAG_PROTO_TRAILER, .xmit = trailer_xmit, .rcv = trailer_rcv, - .overhead = 4, - .tail_tag = true, + .needed_tailroom = 4, }; MODULE_LICENSE("GPL"); diff --git a/net/dsa/tag_xrs700x.c b/net/dsa/tag_xrs700x.c index 858cdf9d2913..a31ff7fcb45f 100644 --- a/net/dsa/tag_xrs700x.c +++ b/net/dsa/tag_xrs700x.c @@ -56,8 +56,7 @@ static const struct dsa_device_ops xrs700x_netdev_ops = { .proto = DSA_TAG_PROTO_XRS700X, .xmit = xrs700x_xmit, .rcv = xrs700x_rcv, - .overhead = 1, - .tail_tag = true, + .needed_tailroom = 1, }; MODULE_LICENSE("GPL"); From patchwork Thu Jun 10 23:26:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 458288 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9B5C3C48BDF for ; Thu, 10 Jun 2021 23:28:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7EC28613E9 for ; Thu, 10 Jun 2021 23:28:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231308AbhFJXaE (ORCPT ); Thu, 10 Jun 2021 19:30:04 -0400 Received: from mail-ej1-f47.google.com ([209.85.218.47]:43614 "EHLO mail-ej1-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231271AbhFJXaA (ORCPT ); Thu, 10 Jun 2021 19:30:00 -0400 Received: by mail-ej1-f47.google.com with SMTP id ci15so1629535ejc.10 for ; Thu, 10 Jun 2021 16:27:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EpbB6OLrl+ZgCUGKVWY3Eyosu/ePuZHBYeJiFQNBWMg=; b=gB5tq6IJxrE+DCi3pOhDOYVe+7S7aHtZdU4liKj2azYoiNGzKDvIthJ8SY+FKpXqtU IgkpNaNPoq1gDldbRtAff3UyEVUR1x7ZzhhxTrgPvgtymbdbJeJ269Paj9SSKfc0p0sw 3tuaLdoIpIyT4uCfItAA/t1tvYNYO2yf3Gfit0NoKZaIBaqMtuj6Gn44L2xxIq7EPH19 TLMJzDxe0iybXT2RDsvW6v+5ixwDl6KL2rdWofMsTrSrsZzzeMnuTvpWUWE05Kuh5gWA qsCUvJe0Abr+XXK1GeFmbZB4hSY0mhbPPuGrGiTYAO68xiwHp30H5hVX40YRl0NKNUxl g0Wg== 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:mime-version:content-transfer-encoding; bh=EpbB6OLrl+ZgCUGKVWY3Eyosu/ePuZHBYeJiFQNBWMg=; b=Y4et1WuWfKK+byz8ziOkYgtumItX8aohoVbos6X55X2fwGPBpJGgCYFWWNUYsPkCyn LC663thfy/JcdWuOCiWGQumjg2wBgZBzqvfipRMKNNWKS94q00usDS/ugc1eZGBM6PSS oSOjdkVAxns4KTp3gxuqnoemM4RVif7vqrg46YHfKWOJEqG4DoozPlCuUYRvC0WGa3kR gAeMP0T+78CZAD9zZLlEf1v6UqapM6MYuN7iP71O8TbkfuhoDvL1+GxB2SG+3P57N5IP HYDiI1ypbbUWlrsn7vTfh2drSj6jpfCBySAa4PavAZGNQccVMuaxIR04jra2TvEjsx8M 32cQ== X-Gm-Message-State: AOAM531cGEe+QUzCvxdDHDEwNAquqpnZw/DrqhXujrFzA1HFJnoSX69x b2211HZSkxOLILTUeiJ65+E= X-Google-Smtp-Source: ABdhPJw5f6fX2FFasGwIOqBckWS8Hw4uL8QakWVTIjbPuMx7nZK4jB4KnqNqlmqSNq1QI231KHyKMw== X-Received: by 2002:a17:906:a850:: with SMTP id dx16mr769719ejb.333.1623367606756; Thu, 10 Jun 2021 16:26:46 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id j22sm1534187ejt.11.2021.06.10.16.26.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:26:46 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Richard Cochran , Vladimir Oltean Subject: [PATCH v2 net-next 04/10] net: dsa: tag_sja1105: stop resetting network and transport headers Date: Fri, 11 Jun 2021 02:26:23 +0300 Message-Id: <20210610232629.1948053-5-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610232629.1948053-1-olteanv@gmail.com> References: <20210610232629.1948053-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean This makes no sense and is not needed, it is probably a debugging leftover. Signed-off-by: Vladimir Oltean --- v1->v2: none net/dsa/tag_sja1105.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c index ff4a81eae16f..92e147293acf 100644 --- a/net/dsa/tag_sja1105.c +++ b/net/dsa/tag_sja1105.c @@ -307,8 +307,6 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb, __skb_vlan_pop(skb, &tci); } skb_pull_rcsum(skb, ETH_HLEN); - skb_reset_network_header(skb); - skb_reset_transport_header(skb); vid = tci & VLAN_VID_MASK; source_port = dsa_8021q_rx_source_port(vid); From patchwork Thu Jun 10 23:26:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 459014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8D6D4C48BDF for ; Thu, 10 Jun 2021 23:28:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 739B0613E9 for ; Thu, 10 Jun 2021 23:28:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230248AbhFJXaI (ORCPT ); Thu, 10 Jun 2021 19:30:08 -0400 Received: from mail-ej1-f48.google.com ([209.85.218.48]:44746 "EHLO mail-ej1-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231209AbhFJXaB (ORCPT ); Thu, 10 Jun 2021 19:30:01 -0400 Received: by mail-ej1-f48.google.com with SMTP id c10so1620704eja.11 for ; Thu, 10 Jun 2021 16:27:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WbLxLivyZ41CT0nx04gBe1r1FFKUcqOUdJMAD/0Doas=; b=WGjinjWzv1LOb1tW1kc3YX/4Pst8ZyTMmX7u53H68KXjxZeQ3g2M5eZI/P6Idc1DPD GJj+DVgsWPInIbfagRvQZu4FAP7EsZ7JRMpuHWjXA4QwEpqFQeo5oN9cuG+Zysv9RXKq CuM14zCKaG443xmkV06VvQ0DCsApeokJbDnMCChb9/NJnChojxRJdnTaoqUGgw3GjCNM Bd7l8ePmhW9bMZmb66W3/aYarz7z6IMDulGTAbluUf5qQwFrmk56mNnn1n+VRvIXLJFH Ov7pc/Mk/XW1q2bELoU7c6tz+GDPVeuwqCGhrWd6RPvThL067DEewKND9zUXkjh0ulLV +y7w== 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:mime-version:content-transfer-encoding; bh=WbLxLivyZ41CT0nx04gBe1r1FFKUcqOUdJMAD/0Doas=; b=swX1BTrxeM89AhN06Vk06irF1UyLMUb54FvNyEyIhjL+cpNd7LTty6rUOSZ3i04aE8 p/RzlPQm8wUdWhq7IJAlO1AgxXydFxHkZd20rzXmUglDA+Ei6RgJma71NAdjCF3rHEw7 QpvXB/lfqT9gTP5EBgM4wS89x8aIacfkdANGCs0x7AZ9juhhD0kdTZQ7wNIuhJl0ciBo NhwEVPex3v2yahDFE7+vAffOn6Iv5rYLsvI57RSPB+XGBD/mA1vDRzdiI0JE5EynS/CL k8Ts2Ig+Tc4XSLyLFcEiHG+JauC6Nh+m5kuwZwg/rV18syTYXPe9zXNEBQeLfn9mGGXS buYg== X-Gm-Message-State: AOAM5305Xuc+7lz+ITfJv2ET3kw9taj3q9C0mi2D+kHBy72mQnAAoVi7 obBkZdNrUwyOSrODL8Fexc0= X-Google-Smtp-Source: ABdhPJxF0+ruMFi6gzd+oypytj8b4Qw6v7whnUW+dOk7faFaBtVAHZFwHTkEjv3YTJLMbEtosvZRvA== X-Received: by 2002:a17:906:b317:: with SMTP id n23mr810872ejz.324.1623367607595; Thu, 10 Jun 2021 16:26:47 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id j22sm1534187ejt.11.2021.06.10.16.26.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:26:47 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Richard Cochran , Vladimir Oltean Subject: [PATCH v2 net-next 05/10] net: dsa: tag_8021q: remove shim declarations Date: Fri, 11 Jun 2021 02:26:24 +0300 Message-Id: <20210610232629.1948053-6-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610232629.1948053-1-olteanv@gmail.com> References: <20210610232629.1948053-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean All users of tag_8021q select it in Kconfig, so shim functions are not needed because it is not possible for it to be disabled and its callers enabled. Signed-off-by: Vladimir Oltean --- v1->v2: none include/linux/dsa/8021q.h | 76 --------------------------------------- 1 file changed, 76 deletions(-) diff --git a/include/linux/dsa/8021q.h b/include/linux/dsa/8021q.h index b12b05f1c8b4..cbf2c9b1ee4f 100644 --- a/include/linux/dsa/8021q.h +++ b/include/linux/dsa/8021q.h @@ -37,8 +37,6 @@ struct dsa_8021q_context { #define DSA_8021Q_N_SUBVLAN 8 -#if IS_ENABLED(CONFIG_NET_DSA_TAG_8021Q) - int dsa_8021q_setup(struct dsa_8021q_context *ctx, bool enabled); int dsa_8021q_crosschip_bridge_join(struct dsa_8021q_context *ctx, int port, @@ -70,78 +68,4 @@ bool vid_is_dsa_8021q_txvlan(u16 vid); bool vid_is_dsa_8021q(u16 vid); -#else - -int dsa_8021q_setup(struct dsa_8021q_context *ctx, bool enabled) -{ - return 0; -} - -int dsa_8021q_crosschip_bridge_join(struct dsa_8021q_context *ctx, int port, - struct dsa_8021q_context *other_ctx, - int other_port) -{ - return 0; -} - -int dsa_8021q_crosschip_bridge_leave(struct dsa_8021q_context *ctx, int port, - struct dsa_8021q_context *other_ctx, - int other_port) -{ - return 0; -} - -struct sk_buff *dsa_8021q_xmit(struct sk_buff *skb, struct net_device *netdev, - u16 tpid, u16 tci) -{ - return NULL; -} - -u16 dsa_8021q_tx_vid(struct dsa_switch *ds, int port) -{ - return 0; -} - -u16 dsa_8021q_rx_vid(struct dsa_switch *ds, int port) -{ - return 0; -} - -u16 dsa_8021q_rx_vid_subvlan(struct dsa_switch *ds, int port, u16 subvlan) -{ - return 0; -} - -int dsa_8021q_rx_switch_id(u16 vid) -{ - return 0; -} - -int dsa_8021q_rx_source_port(u16 vid) -{ - return 0; -} - -u16 dsa_8021q_rx_subvlan(u16 vid) -{ - return 0; -} - -bool vid_is_dsa_8021q_rxvlan(u16 vid) -{ - return false; -} - -bool vid_is_dsa_8021q_txvlan(u16 vid) -{ - return false; -} - -bool vid_is_dsa_8021q(u16 vid) -{ - return false; -} - -#endif /* IS_ENABLED(CONFIG_NET_DSA_TAG_8021Q) */ - #endif /* _NET_DSA_8021Q_H */ From patchwork Thu Jun 10 23:26:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 458291 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 215D2C48BD1 for ; Thu, 10 Jun 2021 23:27:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 02C27613E1 for ; Thu, 10 Jun 2021 23:27:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231164AbhFJX3D (ORCPT ); Thu, 10 Jun 2021 19:29:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230001AbhFJX3A (ORCPT ); Thu, 10 Jun 2021 19:29:00 -0400 Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E75BBC0617AD for ; Thu, 10 Jun 2021 16:26:49 -0700 (PDT) Received: by mail-ej1-x62e.google.com with SMTP id he7so1604446ejc.13 for ; Thu, 10 Jun 2021 16:26:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZSgohKs2envCiVjM700hVzegGBGaFDjKn8R8u5q1zwM=; b=I8yAzi7BxV7fB2G43RI4RZiz9sH7BuLoCkx9zJHiJD4h1lhdmln0EsRyD1DJW1c0aU iy8i9mgr13YHbO+uq1H7ubgUY7b+yIXahvxLI2s9KdiC95XEwGRoV1pwWpyaaYQOJkIi yDAF8dTlajzbb7nJcqVC+bvsM+iMe1mlZmqeDkUpmnU+LePgh3uy0fTa7vnH0l2GPjeq vsWz3So/S+y3iQHp/xu0ZBvXTeAcPFxaDU0fOAz1aB47bCBkN1kEt1UViBSOGhHaTUP9 2/Kh/r62ntbxaJok7JSwFPxDltbS/koRdhPDyIYBQFQmzIVsdp60str3sfA4S2KDlXgJ 1m0g== 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:mime-version:content-transfer-encoding; bh=ZSgohKs2envCiVjM700hVzegGBGaFDjKn8R8u5q1zwM=; b=DE4NxasB+JqeEbbKhDzuf3wJJQo+s0Hx+hpY/DR7wNT0CmdVqDf5LXljR8UQsw3Qjg SwfozXPKpdn++f5jeBpGc/WIcvuSZWDnqVGYVLIpUFWjaW0Uww56ANqryxNDzEc5dnIG abjwKqJMHkWaiSA4k86TAswrW9zBHPaSqsDSEK3ovRTNoixCPAHVqU+bEe0V5Vryubnp PdAWubysdwVEX51YGo2xTgp1KwllV81ewU0Zp388cZTM/vGhQfFc+ugYtiZSSGjS5bcT XW6PTSj6bIN/Wy6G7cu8WZfAaXHI9yOEiJZaB3iwHdNOuT6JPDrH+F+k7iKV99GVqYtK nqZQ== X-Gm-Message-State: AOAM531kQUpQ/e/eU0ZsHuSjPVA5vTPXrRS6yYeXGTaiMCG+vecS3UGM 9pU+bl3O241CrGOmZLsuAB4= X-Google-Smtp-Source: ABdhPJxaC9ToPbXduLK6SX73+7fOBzSZgq38kIRVd7ngNuNygW0Mqwa83QfagZjD52XOdFDlcuMRAQ== X-Received: by 2002:a17:906:f889:: with SMTP id lg9mr810199ejb.82.1623367608481; Thu, 10 Jun 2021 16:26:48 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id j22sm1534187ejt.11.2021.06.10.16.26.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:26:48 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Richard Cochran , Vladimir Oltean Subject: [PATCH v2 net-next 06/10] net: dsa: tag_8021q: refactor RX VLAN parsing into a dedicated function Date: Fri, 11 Jun 2021 02:26:25 +0300 Message-Id: <20210610232629.1948053-7-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610232629.1948053-1-olteanv@gmail.com> References: <20210610232629.1948053-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean The added value of this function is that it can deal with both the case where the VLAN header is in the skb head, as well as in the offload field. This is something I was not able to do using other functions in the network stack. Since both ocelot-8021q and sja1105 need to do the same stuff, let's make it a common service provided by tag_8021q. This is done as refactoring for the new SJA1110 tagger, which partly uses tag_8021q as well (just like SJA1105), and will be the third caller. Signed-off-by: Vladimir Oltean --- v1->v2: export the dsa_8021q_rcv symbol to avoid build errors when building as module include/linux/dsa/8021q.h | 3 +++ net/dsa/tag_8021q.c | 23 +++++++++++++++++++++++ net/dsa/tag_ocelot_8021q.c | 18 ++---------------- net/dsa/tag_sja1105.c | 33 +++++++++++---------------------- 4 files changed, 39 insertions(+), 38 deletions(-) diff --git a/include/linux/dsa/8021q.h b/include/linux/dsa/8021q.h index cbf2c9b1ee4f..1587961f1a7b 100644 --- a/include/linux/dsa/8021q.h +++ b/include/linux/dsa/8021q.h @@ -50,6 +50,9 @@ int dsa_8021q_crosschip_bridge_leave(struct dsa_8021q_context *ctx, int port, struct sk_buff *dsa_8021q_xmit(struct sk_buff *skb, struct net_device *netdev, u16 tpid, u16 tci); +void dsa_8021q_rcv(struct sk_buff *skb, int *source_port, int *switch_id, + int *subvlan); + u16 dsa_8021q_tx_vid(struct dsa_switch *ds, int port); u16 dsa_8021q_rx_vid(struct dsa_switch *ds, int port); diff --git a/net/dsa/tag_8021q.c b/net/dsa/tag_8021q.c index 122ad5833fb1..4aa29f90ecea 100644 --- a/net/dsa/tag_8021q.c +++ b/net/dsa/tag_8021q.c @@ -471,4 +471,27 @@ struct sk_buff *dsa_8021q_xmit(struct sk_buff *skb, struct net_device *netdev, } EXPORT_SYMBOL_GPL(dsa_8021q_xmit); +void dsa_8021q_rcv(struct sk_buff *skb, int *source_port, int *switch_id, + int *subvlan) +{ + u16 vid, tci; + + skb_push_rcsum(skb, ETH_HLEN); + if (skb_vlan_tag_present(skb)) { + tci = skb_vlan_tag_get(skb); + __vlan_hwaccel_clear_tag(skb); + } else { + __skb_vlan_pop(skb, &tci); + } + skb_pull_rcsum(skb, ETH_HLEN); + + vid = tci & VLAN_VID_MASK; + + *source_port = dsa_8021q_rx_source_port(vid); + *switch_id = dsa_8021q_rx_switch_id(vid); + *subvlan = dsa_8021q_rx_subvlan(vid); + skb->priority = (tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; +} +EXPORT_SYMBOL_GPL(dsa_8021q_rcv); + MODULE_LICENSE("GPL v2"); diff --git a/net/dsa/tag_ocelot_8021q.c b/net/dsa/tag_ocelot_8021q.c index 663b74793cfc..85ac85c3af8c 100644 --- a/net/dsa/tag_ocelot_8021q.c +++ b/net/dsa/tag_ocelot_8021q.c @@ -41,29 +41,15 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, struct net_device *netdev, struct packet_type *pt) { - int src_port, switch_id, qos_class; - u16 vid, tci; + int src_port, switch_id, subvlan; - skb_push_rcsum(skb, ETH_HLEN); - if (skb_vlan_tag_present(skb)) { - tci = skb_vlan_tag_get(skb); - __vlan_hwaccel_clear_tag(skb); - } else { - __skb_vlan_pop(skb, &tci); - } - skb_pull_rcsum(skb, ETH_HLEN); - - vid = tci & VLAN_VID_MASK; - src_port = dsa_8021q_rx_source_port(vid); - switch_id = dsa_8021q_rx_switch_id(vid); - qos_class = (tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; + dsa_8021q_rcv(skb, &src_port, &switch_id, &subvlan); skb->dev = dsa_master_find_slave(netdev, switch_id, src_port); if (!skb->dev) return NULL; skb->offload_fwd_mark = 1; - skb->priority = qos_class; return skb; } diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c index 92e147293acf..a70625fe64f7 100644 --- a/net/dsa/tag_sja1105.c +++ b/net/dsa/tag_sja1105.c @@ -275,44 +275,33 @@ static void sja1105_decode_subvlan(struct sk_buff *skb, u16 subvlan) __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci); } +static bool sja1105_skb_has_tag_8021q(const struct sk_buff *skb) +{ + u16 tpid = ntohs(eth_hdr(skb)->h_proto); + + return tpid == ETH_P_SJA1105 || tpid == ETH_P_8021Q || + skb_vlan_tag_present(skb); +} + static struct sk_buff *sja1105_rcv(struct sk_buff *skb, struct net_device *netdev, struct packet_type *pt) { + int source_port, switch_id, subvlan = 0; struct sja1105_meta meta = {0}; - int source_port, switch_id; struct ethhdr *hdr; - u16 tpid, vid, tci; bool is_link_local; - u16 subvlan = 0; - bool is_tagged; bool is_meta; hdr = eth_hdr(skb); - tpid = ntohs(hdr->h_proto); - is_tagged = (tpid == ETH_P_SJA1105 || tpid == ETH_P_8021Q || - skb_vlan_tag_present(skb)); is_link_local = sja1105_is_link_local(skb); is_meta = sja1105_is_meta_frame(skb); skb->offload_fwd_mark = 1; - if (is_tagged) { + if (sja1105_skb_has_tag_8021q(skb)) { /* Normal traffic path. */ - skb_push_rcsum(skb, ETH_HLEN); - if (skb_vlan_tag_present(skb)) { - tci = skb_vlan_tag_get(skb); - __vlan_hwaccel_clear_tag(skb); - } else { - __skb_vlan_pop(skb, &tci); - } - skb_pull_rcsum(skb, ETH_HLEN); - - vid = tci & VLAN_VID_MASK; - source_port = dsa_8021q_rx_source_port(vid); - switch_id = dsa_8021q_rx_switch_id(vid); - skb->priority = (tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; - subvlan = dsa_8021q_rx_subvlan(vid); + dsa_8021q_rcv(skb, &source_port, &switch_id, &subvlan); } else if (is_link_local) { /* Management traffic path. Switch embeds the switch ID and * port ID into bytes of the destination MAC, courtesy of From patchwork Thu Jun 10 23:26:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 459015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1708CC48BDF for ; Thu, 10 Jun 2021 23:28:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EE0D1613E9 for ; Thu, 10 Jun 2021 23:28:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231287AbhFJXaB (ORCPT ); Thu, 10 Jun 2021 19:30:01 -0400 Received: from mail-ej1-f48.google.com ([209.85.218.48]:44750 "EHLO mail-ej1-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231269AbhFJXaA (ORCPT ); Thu, 10 Jun 2021 19:30:00 -0400 Received: by mail-ej1-f48.google.com with SMTP id c10so1620786eja.11 for ; Thu, 10 Jun 2021 16:27:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+gTZUnVosgobVHSPhlK1YMC8IZT5HvZOpg52duA+dlc=; b=NKmRmuxmN+wJERHISTCypVAZkvtC1pE5lghKnYD0Vh52s6TW+nBG0CCOOM/VSnbFt5 vpb9Yn00ThQGUaI76Zdhku+L7/osGVNVD8MGdCXRlCLlRi/BPT4AMNhWOH8ms6pWO5Mw zYTczIP6AihmCEGjiFn3RTsJCIHKZpqNNCYk/HyOkFm8f+fPuezeJYHjm9Pn5XR3dDnl kxhrf4zG4CbtupbLBrliZCrk5ONhJrTnkg2ccgE0/ar+wv1VPHhvNW3LrVGpcZrr+VSe WeE/tueSezxUK2LE79xF74M6X5l6E/NflGODSXva05YAre9SBqM4J8mtG7PPgk8m/HMl C3rA== 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:mime-version:content-transfer-encoding; bh=+gTZUnVosgobVHSPhlK1YMC8IZT5HvZOpg52duA+dlc=; b=arT8OsT+a2q4L0kJtw4XhqvjVg6hZ7Toqr2uMZxcHNLwuFa9ETJh6EgfSzuNu6cmom ATnhhYMjalf2jIKNyI1g1zLOxvT4xrQvSMAHfB9UpL8HSiuMxZp9FjQhIRzeagRlnwl7 nO4Y6ml+YURu3Wfnzo9PywgQj4m9S5wBaTE7/x/hHFq8joyWAgdsLo6eno3Hb9J/Ngsj RJjTb9NKV83ZswYX4XEfDWMqW2y5sMFGzaVXXdEY602JJbuLiw1n8DTnkUIlVlhqWuzD GieSgQFou2tkWV/0WQixRhyYlr2XVaXi6TW/EuIf3yBySaKJ3bRsHiAe9xhG1XAx9eH7 ZR9w== X-Gm-Message-State: AOAM532LtHxSn1BWkhAYHGhz9RLVufLKCVpT68/n1t58EQXY6FM8IpgA Mnzf0hGYs3J06TWvPOBJPiE= X-Google-Smtp-Source: ABdhPJwnRj8L8oM5Y851ed5QFd8lCCHnk4+cpWnQgSxE84ejAfuOxlyJ+7dsK1ofdorGQ8WKuu0vDg== X-Received: by 2002:a17:906:b84f:: with SMTP id ga15mr767816ejb.372.1623367609482; Thu, 10 Jun 2021 16:26:49 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id j22sm1534187ejt.11.2021.06.10.16.26.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:26:49 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Richard Cochran , Vladimir Oltean Subject: [PATCH v2 net-next 07/10] net: dsa: sja1105: make SJA1105_SKB_CB fit a full timestamp Date: Fri, 11 Jun 2021 02:26:26 +0300 Message-Id: <20210610232629.1948053-8-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610232629.1948053-1-olteanv@gmail.com> References: <20210610232629.1948053-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean In SJA1105, RX timestamps for packets sent to the CPU are transmitted in separate follow-up packets (metadata frames). These contain partial timestamps (24 or 32 bits) which are kept in SJA1105_SKB_CB(skb)->meta_tstamp. Thankfully, SJA1110 improved that, and the RX timestamps are now transmitted in-band with the actual packet, in the timestamp trailer. The RX timestamps are now full-width 64 bits. Because we process the RX DSA tags in the rcv() method in the tagger, but we would like to preserve the DSA code structure in that we populate the skb timestamp in the port_rxtstamp() call which only happens later, the implication is that we must somehow pass the 64-bit timestamp from the rcv() method all the way to port_rxtstamp(). We can use the skb->cb for that. Rename the meta_tstamp from struct sja1105_skb_cb from "meta_tstamp" to "tstamp", and increase its size to 64 bits. Signed-off-by: Vladimir Oltean --- v1->v2: none drivers/net/dsa/sja1105/sja1105_ptp.c | 2 +- include/linux/dsa/sja1105.h | 2 +- net/dsa/tag_sja1105.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c index 0bc566b9e958..dea82f8a40c4 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.c +++ b/drivers/net/dsa/sja1105/sja1105_ptp.c @@ -397,7 +397,7 @@ static long sja1105_rxtstamp_work(struct ptp_clock_info *ptp) *shwt = (struct skb_shared_hwtstamps) {0}; - ts = SJA1105_SKB_CB(skb)->meta_tstamp; + ts = SJA1105_SKB_CB(skb)->tstamp; ts = sja1105_tstamp_reconstruct(ds, ticks, ts); shwt->hwtstamp = ns_to_ktime(sja1105_ticks_to_ns(ts)); diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h index 1eb84562b311..865a548a6ef2 100644 --- a/include/linux/dsa/sja1105.h +++ b/include/linux/dsa/sja1105.h @@ -48,7 +48,7 @@ struct sja1105_tagger_data { struct sja1105_skb_cb { struct sk_buff *clone; - u32 meta_tstamp; + u64 tstamp; }; #define SJA1105_SKB_CB(skb) \ diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c index a70625fe64f7..11f555dd9566 100644 --- a/net/dsa/tag_sja1105.c +++ b/net/dsa/tag_sja1105.c @@ -147,7 +147,7 @@ static void sja1105_transfer_meta(struct sk_buff *skb, hdr->h_dest[3] = meta->dmac_byte_3; hdr->h_dest[4] = meta->dmac_byte_4; - SJA1105_SKB_CB(skb)->meta_tstamp = meta->tstamp; + SJA1105_SKB_CB(skb)->tstamp = meta->tstamp; } /* This is a simple state machine which follows the hardware mechanism of From patchwork Thu Jun 10 23:26:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 458287 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80687C48BD1 for ; Thu, 10 Jun 2021 23:28:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5EF63613CB for ; Thu, 10 Jun 2021 23:28:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231338AbhFJXaL (ORCPT ); Thu, 10 Jun 2021 19:30:11 -0400 Received: from mail-ej1-f54.google.com ([209.85.218.54]:41711 "EHLO mail-ej1-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231284AbhFJXaC (ORCPT ); Thu, 10 Jun 2021 19:30:02 -0400 Received: by mail-ej1-f54.google.com with SMTP id ho18so1642974ejc.8 for ; Thu, 10 Jun 2021 16:27:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=84+ZAqVTTuq/CdMoNaJWkPOH/2sGQ/kXlUJMmPwYF5A=; b=DLoja170wkSintznANR2yelFbcgX1mu2FbgaSxiSxxmkZNy4KFQ2ehZ2YRFHlxuC9M p2RI/RLkul5STt+gS19yHj1yUzC2o44M8qTnqo5ZV5v6AvZblM3PqU5lSjXn/yFcNuHt 9PKCgpSWprzFGN++nzjcC/g28fL+k+zSJG8x3GadfZtaQcnFBkSHrBWjjqWOaTdVJ1Rc LjK3fgX0V59TIVvU7leb+lxSQ0RVYfHhyTGiz/BGRg0IP0DoMxmVL4l6TWwJ4yQbqrSE fOYP/RanQNNQhRh2OG/1ANzVJBzbhngWW7M8FgrUIVeQGElXLuaxSg7clOo6rmr+48Q4 QPfw== 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:mime-version:content-transfer-encoding; bh=84+ZAqVTTuq/CdMoNaJWkPOH/2sGQ/kXlUJMmPwYF5A=; b=UeL3eKgRZ0ejx0s0pI7OV0WZ4IMr878I3UZTiYOGzfBdZmUHMyVnz5/YOzcZz3fMoz GhHTeLjz4qORyFyp5GEU3lwhtkpdVRuaO9yS+jo9F7Q/ePX+LOz/gQEiBPLuDBH1wOBB 3jopQt2Iy2sp/Rl0JQyoXiYK/XcFZeydebSJGDrTG9mDZla85fDe4T5VaXhY7k7HOUdq WM6VjpQssVM9Y8px/jOlh51l7Kx7d/7iJcy7fIJeUc4A0eb19bnselzL6kmD66ObRKWW aO/dVeKAg2+wwjvxNK2Mj3qG7Hfr3AGh6fQinZ5tP/X4VOWIYLgTobRFcpmIKRP3QZo0 VoLQ== X-Gm-Message-State: AOAM533VkVaJuNc85+vQZ7t6Ya6L3IYFakZ0aLezaMeK3G83YUOsjBfS avX7MnmGLYz0GidMQ5owCJd/Lk5rT9Q= X-Google-Smtp-Source: ABdhPJyMr61dlHOL6rM++KDv//ybBD8gBK+zB/kVwW5CNdGGt8uoo9EgAD6jfBi/p64fCEwNXkOlSQ== X-Received: by 2002:a17:906:81da:: with SMTP id e26mr772308ejx.370.1623367610346; Thu, 10 Jun 2021 16:26:50 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id j22sm1534187ejt.11.2021.06.10.16.26.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:26:50 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Richard Cochran , Vladimir Oltean Subject: [PATCH v2 net-next 08/10] net: dsa: add support for the SJA1110 native tagging protocol Date: Fri, 11 Jun 2021 02:26:27 +0300 Message-Id: <20210610232629.1948053-9-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610232629.1948053-1-olteanv@gmail.com> References: <20210610232629.1948053-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean The SJA1110 has improved a few things compared to SJA1105: - To send a control packet from the host port with SJA1105, one needed to program a one-shot "management route" over SPI. This is no longer true with SJA1110, you can actually send "in-band control extensions" in the packets sent by DSA, these are in fact DSA tags which contain the destination port and switch ID. - When receiving a control packet from the switch with SJA1105, the source port and switch ID were written in bytes 3 and 4 of the destination MAC address of the frame (which was a very poor shot at a DSA header). If the control packet also had an RX timestamp, that timestamp was sent in an actual follow-up packet, so there were reordering concerns on multi-core/multi-queue DSA masters, where the metadata frame with the RX timestamp might get processed before the actual packet to which that timestamp belonged (there is no way to pair a packet to its timestamp other than the order in which they were received). On SJA1110, this is no longer true, control packets have the source port, switch ID and timestamp all in the DSA tags. - Timestamps from the switch were partial: to get a 64-bit timestamp as required by PTP stacks, one would need to take the partial 24-bit or 32-bit timestamp from the packet, then read the current PTP time very quickly, and then patch in the high bits of the current PTP time into the captured partial timestamp, to reconstruct what the full 64-bit timestamp must have been. That is awful because packet processing is done in NAPI context, but reading the current PTP time is done over SPI and therefore needs sleepable context. But it also aggravated a few things: - Not only is there a DSA header in SJA1110, but there is a DSA trailer in fact, too. So DSA needs to be extended to support taggers which have both a header and a trailer. Very unconventional - my understanding is that the trailer exists because the timestamps couldn't be prepared in time for putting them in the header area. - Like SJA1105, not all packets sent to the CPU have the DSA tag added to them, only control packets do: * the ones which match the destination MAC filters/traps in MAC_FLTRES1 and MAC_FLTRES0 * the ones which match FDB entries which have TRAP or TAKETS bits set So we could in theory hack something up to request the switch to take timestamps for all packets that reach the CPU, and those would be DSA-tagged and contain the source port / switch ID by virtue of the fact that there needs to be a timestamp trailer provided. BUT: - The SJA1110 does not parse its own DSA tags in a way that is useful for routing in cross-chip topologies, a la Marvell. And the sja1105 driver already supports cross-chip bridging from the SJA1105 days. It does that by automatically setting up the DSA links as VLAN trunks which contain all the necessary tag_8021q RX VLANs that must be communicated between the switches that span the same bridge. So when using tag_8021q on sja1105, it is possible to have 2 switches with ports sw0p0, sw0p1, sw1p0, sw1p1, and 2 VLAN-unaware bridges br0 and br1, and br0 can take sw0p0 and sw1p0, and br1 can take sw0p1 and sw1p1, and forwarding will happen according to the expected rules of the Linux bridge. We like that, and we don't want that to go away, so as a matter of fact, the SJA1110 tagger still needs to support tag_8021q. So the sja1110 tagger is a hybrid between tag_8021q for data packets, and the native hardware support for control packets. On RX, packets have a 13-byte trailer if they contain an RX timestamp. That trailer is padded in such a way that its byte 8 (the start of the "residence time" field - not parsed by Linux because we don't care) is aligned on a 16 byte boundary. So the padding has a variable length between 0 and 15 bytes. The DSA header contains the offset of the beginning of the padding relative to the beginning of the frame (and the end of the padding is obviously the end of the packet minus 13 bytes, the length of the trailer). So we discard it. Packets which don't have a trailer contain the source port and switch ID information in the header (they are "trap-to-host" packets). Packets which have a trailer contain the source port and switch ID in the trailer. On TX, the destination port mask and switch ID is always in the trailer, so we always need to say in the header that a trailer is present. The header needs a custom EtherType and this was chosen as 0xdadc, after 0xdada which is for Marvell and 0xdadb which is for VLANs in VLAN-unaware mode on SJA1105 (and SJA1110 in fact too). Because we use tag_8021q in concert with the native tagging protocol, control packets will have 2 DSA tags. Signed-off-by: Vladimir Oltean --- v1->v2: none drivers/net/dsa/sja1105/sja1105.h | 1 + drivers/net/dsa/sja1105/sja1105_main.c | 6 +- drivers/net/dsa/sja1105/sja1105_spi.c | 10 + .../net/dsa/sja1105/sja1105_static_config.c | 1 + .../net/dsa/sja1105/sja1105_static_config.h | 1 + include/linux/dsa/sja1105.h | 1 + include/net/dsa.h | 2 + net/dsa/tag_sja1105.c | 221 +++++++++++++++++- 8 files changed, 240 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index cd45e9558425..fcba65719267 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -111,6 +111,7 @@ struct sja1105_info { int max_frame_mem; int num_ports; bool multiple_cascade_ports; + enum dsa_tag_protocol tag_proto; const struct sja1105_dynamic_table_ops *dyn_ops; const struct sja1105_table_ops *static_ops; const struct sja1105_regs *regs; diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 4e73a4abb09a..8e5cdf93c23b 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -669,6 +669,8 @@ static int sja1105_init_general_params(struct sja1105_private *priv) .tpid2 = ETH_P_SJA1105, /* Enable the TTEthernet engine on SJA1110 */ .tte_en = true, + /* Set up the EtherType for control packets on SJA1110 */ + .header_type = ETH_P_SJA1110, }; struct sja1105_general_params_entry *general_params; struct dsa_switch *ds = priv->ds; @@ -2067,7 +2069,9 @@ static enum dsa_tag_protocol sja1105_get_tag_protocol(struct dsa_switch *ds, int port, enum dsa_tag_protocol mp) { - return DSA_TAG_PROTO_SJA1105; + struct sja1105_private *priv = ds->priv; + + return priv->info->tag_proto; } static int sja1105_find_free_subvlan(u16 *subvlan_map, bool pvid) diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 1eae25007167..0d4158fdeec0 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -572,6 +572,7 @@ const struct sja1105_info sja1105e_info = { .static_ops = sja1105e_table_ops, .dyn_ops = sja1105et_dyn_ops, .qinq_tpid = ETH_P_8021Q, + .tag_proto = DSA_TAG_PROTO_SJA1105, .can_limit_mcast_flood = false, .ptp_ts_bits = 24, .ptpegr_ts_bytes = 4, @@ -603,6 +604,7 @@ const struct sja1105_info sja1105t_info = { .static_ops = sja1105t_table_ops, .dyn_ops = sja1105et_dyn_ops, .qinq_tpid = ETH_P_8021Q, + .tag_proto = DSA_TAG_PROTO_SJA1105, .can_limit_mcast_flood = false, .ptp_ts_bits = 24, .ptpegr_ts_bytes = 4, @@ -634,6 +636,7 @@ const struct sja1105_info sja1105p_info = { .static_ops = sja1105p_table_ops, .dyn_ops = sja1105pqrs_dyn_ops, .qinq_tpid = ETH_P_8021AD, + .tag_proto = DSA_TAG_PROTO_SJA1105, .can_limit_mcast_flood = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, @@ -666,6 +669,7 @@ const struct sja1105_info sja1105q_info = { .static_ops = sja1105q_table_ops, .dyn_ops = sja1105pqrs_dyn_ops, .qinq_tpid = ETH_P_8021AD, + .tag_proto = DSA_TAG_PROTO_SJA1105, .can_limit_mcast_flood = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, @@ -698,6 +702,7 @@ const struct sja1105_info sja1105r_info = { .static_ops = sja1105r_table_ops, .dyn_ops = sja1105pqrs_dyn_ops, .qinq_tpid = ETH_P_8021AD, + .tag_proto = DSA_TAG_PROTO_SJA1105, .can_limit_mcast_flood = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, @@ -734,6 +739,7 @@ const struct sja1105_info sja1105s_info = { .dyn_ops = sja1105pqrs_dyn_ops, .regs = &sja1105pqrs_regs, .qinq_tpid = ETH_P_8021AD, + .tag_proto = DSA_TAG_PROTO_SJA1105, .can_limit_mcast_flood = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, @@ -769,6 +775,7 @@ const struct sja1105_info sja1110a_info = { .dyn_ops = sja1110_dyn_ops, .regs = &sja1110_regs, .qinq_tpid = ETH_P_8021AD, + .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, .ptp_ts_bits = 32, @@ -817,6 +824,7 @@ const struct sja1105_info sja1110b_info = { .dyn_ops = sja1110_dyn_ops, .regs = &sja1110_regs, .qinq_tpid = ETH_P_8021AD, + .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, .ptp_ts_bits = 32, @@ -865,6 +873,7 @@ const struct sja1105_info sja1110c_info = { .dyn_ops = sja1110_dyn_ops, .regs = &sja1110_regs, .qinq_tpid = ETH_P_8021AD, + .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, .ptp_ts_bits = 32, @@ -913,6 +922,7 @@ const struct sja1105_info sja1110d_info = { .dyn_ops = sja1110_dyn_ops, .regs = &sja1110_regs, .qinq_tpid = ETH_P_8021AD, + .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, .ptp_ts_bits = 32, diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.c b/drivers/net/dsa/sja1105/sja1105_static_config.c index eda571819d45..1491b72008f3 100644 --- a/drivers/net/dsa/sja1105/sja1105_static_config.c +++ b/drivers/net/dsa/sja1105/sja1105_static_config.c @@ -212,6 +212,7 @@ size_t sja1110_general_params_entry_packing(void *buf, void *entry_ptr, sja1105_packing(buf, &entry->egrmirrdei, 110, 110, size, op); sja1105_packing(buf, &entry->replay_port, 109, 106, size, op); sja1105_packing(buf, &entry->tdmaconfigidx, 70, 67, size, op); + sja1105_packing(buf, &entry->header_type, 64, 49, size, op); sja1105_packing(buf, &entry->tte_en, 16, 16, size, op); return size; } diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.h b/drivers/net/dsa/sja1105/sja1105_static_config.h index 9bef51791bff..bce0f5c03d0b 100644 --- a/drivers/net/dsa/sja1105/sja1105_static_config.h +++ b/drivers/net/dsa/sja1105/sja1105_static_config.h @@ -217,6 +217,7 @@ struct sja1105_general_params_entry { /* SJA1110 only */ u64 tte_en; u64 tdmaconfigidx; + u64 header_type; }; struct sja1105_schedule_entry_points_entry { diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h index 865a548a6ef2..b02cf7b515ae 100644 --- a/include/linux/dsa/sja1105.h +++ b/include/linux/dsa/sja1105.h @@ -14,6 +14,7 @@ #define ETH_P_SJA1105 ETH_P_DSA_8021Q #define ETH_P_SJA1105_META 0x0008 +#define ETH_P_SJA1110 0xdadc /* IEEE 802.3 Annex 57A: Slow Protocols PDUs (01:80:C2:xx:xx:xx) */ #define SJA1105_LINKLOCAL_FILTER_A 0x0180C2000000ull diff --git a/include/net/dsa.h b/include/net/dsa.h index 0a10f6fffc3d..289d68e82da0 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -50,6 +50,7 @@ struct phylink_link_state; #define DSA_TAG_PROTO_OCELOT_8021Q_VALUE 20 #define DSA_TAG_PROTO_SEVILLE_VALUE 21 #define DSA_TAG_PROTO_BRCM_LEGACY_VALUE 22 +#define DSA_TAG_PROTO_SJA1110_VALUE 23 enum dsa_tag_protocol { DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, @@ -75,6 +76,7 @@ enum dsa_tag_protocol { DSA_TAG_PROTO_XRS700X = DSA_TAG_PROTO_XRS700X_VALUE, DSA_TAG_PROTO_OCELOT_8021Q = DSA_TAG_PROTO_OCELOT_8021Q_VALUE, DSA_TAG_PROTO_SEVILLE = DSA_TAG_PROTO_SEVILLE_VALUE, + DSA_TAG_PROTO_SJA1110 = DSA_TAG_PROTO_SJA1110_VALUE, }; struct packet_type; diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c index 11f555dd9566..37e1d64e07c6 100644 --- a/net/dsa/tag_sja1105.c +++ b/net/dsa/tag_sja1105.c @@ -7,6 +7,47 @@ #include #include "dsa_priv.h" +/* Is this a TX or an RX header? */ +#define SJA1110_HEADER_HOST_TO_SWITCH BIT(15) + +/* RX header */ +#define SJA1110_RX_HEADER_IS_METADATA BIT(14) +#define SJA1110_RX_HEADER_HOST_ONLY BIT(13) +#define SJA1110_RX_HEADER_HAS_TRAILER BIT(12) + +/* Trap-to-host format (no trailer present) */ +#define SJA1110_RX_HEADER_SRC_PORT(x) (((x) & GENMASK(7, 4)) >> 4) +#define SJA1110_RX_HEADER_SWITCH_ID(x) ((x) & GENMASK(3, 0)) + +/* Timestamp format (trailer present) */ +#define SJA1110_RX_HEADER_TRAILER_POS(x) ((x) & GENMASK(11, 0)) + +#define SJA1110_RX_TRAILER_SWITCH_ID(x) (((x) & GENMASK(7, 4)) >> 4) +#define SJA1110_RX_TRAILER_SRC_PORT(x) ((x) & GENMASK(3, 0)) + +/* TX header */ +#define SJA1110_TX_HEADER_UPDATE_TC BIT(14) +#define SJA1110_TX_HEADER_TAKE_TS BIT(13) +#define SJA1110_TX_HEADER_TAKE_TS_CASC BIT(12) +#define SJA1110_TX_HEADER_HAS_TRAILER BIT(11) + +/* Only valid if SJA1110_TX_HEADER_HAS_TRAILER is false */ +#define SJA1110_TX_HEADER_PRIO(x) (((x) << 7) & GENMASK(10, 7)) +#define SJA1110_TX_HEADER_TSTAMP_ID(x) ((x) & GENMASK(7, 0)) + +/* Only valid if SJA1110_TX_HEADER_HAS_TRAILER is true */ +#define SJA1110_TX_HEADER_TRAILER_POS(x) ((x) & GENMASK(10, 0)) + +#define SJA1110_TX_TRAILER_TSTAMP_ID(x) (((x) << 24) & GENMASK(31, 24)) +#define SJA1110_TX_TRAILER_PRIO(x) (((x) << 21) & GENMASK(23, 21)) +#define SJA1110_TX_TRAILER_SWITCHID(x) (((x) << 12) & GENMASK(15, 12)) +#define SJA1110_TX_TRAILER_DESTPORTS(x) (((x) << 1) & GENMASK(11, 1)) + +#define SJA1110_HEADER_LEN 4 +#define SJA1110_RX_TRAILER_LEN 13 +#define SJA1110_TX_TRAILER_LEN 4 +#define SJA1110_MAX_PADDING_LEN 15 + /* Similar to is_link_local_ether_addr(hdr->h_dest) but also covers PTP */ static inline bool sja1105_is_link_local(const struct sk_buff *skb) { @@ -140,6 +181,50 @@ static struct sk_buff *sja1105_xmit(struct sk_buff *skb, ((pcp << VLAN_PRIO_SHIFT) | tx_vid)); } +static struct sk_buff *sja1110_xmit(struct sk_buff *skb, + struct net_device *netdev) +{ + struct dsa_port *dp = dsa_slave_to_port(netdev); + u16 tx_vid = dsa_8021q_tx_vid(dp->ds, dp->index); + u16 queue_mapping = skb_get_queue_mapping(skb); + u8 pcp = netdev_txq_to_tc(netdev, queue_mapping); + struct ethhdr *eth_hdr; + __be32 *tx_trailer; + __be16 *tx_header; + int trailer_pos; + + /* Transmitting control packets is done using in-band control + * extensions, while data packets are transmitted using + * tag_8021q TX VLANs. + */ + if (likely(!sja1105_is_link_local(skb))) + return dsa_8021q_xmit(skb, netdev, sja1105_xmit_tpid(dp->priv), + ((pcp << VLAN_PRIO_SHIFT) | tx_vid)); + + skb_push(skb, SJA1110_HEADER_LEN); + + /* Move Ethernet header to the left, making space for DSA tag */ + memmove(skb->data, skb->data + SJA1110_HEADER_LEN, 2 * ETH_ALEN); + + trailer_pos = skb->len; + + /* On TX, skb->data points to skb_mac_header(skb) */ + eth_hdr = (struct ethhdr *)skb->data; + tx_header = (__be16 *)(eth_hdr + 1); + tx_trailer = skb_put(skb, SJA1110_TX_TRAILER_LEN); + + eth_hdr->h_proto = htons(ETH_P_SJA1110); + + *tx_header = htons(SJA1110_HEADER_HOST_TO_SWITCH | + SJA1110_TX_HEADER_HAS_TRAILER | + SJA1110_TX_HEADER_TRAILER_POS(trailer_pos)); + *tx_trailer = cpu_to_be32(SJA1110_TX_TRAILER_PRIO(pcp) | + SJA1110_TX_TRAILER_SWITCHID(dp->ds->index) | + SJA1110_TX_TRAILER_DESTPORTS(BIT(dp->index))); + + return skb; +} + static void sja1105_transfer_meta(struct sk_buff *skb, const struct sja1105_meta *meta) { @@ -283,6 +368,11 @@ static bool sja1105_skb_has_tag_8021q(const struct sk_buff *skb) skb_vlan_tag_present(skb); } +static bool sja1110_skb_has_inband_control_extension(const struct sk_buff *skb) +{ + return ntohs(eth_hdr(skb)->h_proto) == ETH_P_SJA1110; +} + static struct sk_buff *sja1105_rcv(struct sk_buff *skb, struct net_device *netdev, struct packet_type *pt) @@ -333,6 +423,98 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb, is_meta); } +static struct sk_buff *sja1110_rcv_inband_control_extension(struct sk_buff *skb, + int *source_port, + int *switch_id) +{ + u16 rx_header; + + if (unlikely(!pskb_may_pull(skb, SJA1110_HEADER_LEN))) + return NULL; + + /* skb->data points to skb_mac_header(skb) + ETH_HLEN, which is exactly + * what we need because the caller has checked the EtherType (which is + * located 2 bytes back) and we just need a pointer to the header that + * comes afterwards. + */ + rx_header = ntohs(*(__be16 *)skb->data); + + /* Timestamp frame, we have a trailer */ + if (rx_header & SJA1110_RX_HEADER_HAS_TRAILER) { + int start_of_padding = SJA1110_RX_HEADER_TRAILER_POS(rx_header); + u8 *rx_trailer = skb_tail_pointer(skb) - SJA1110_RX_TRAILER_LEN; + u64 *tstamp = &SJA1105_SKB_CB(skb)->tstamp; + u8 last_byte = rx_trailer[12]; + + /* The timestamp is unaligned, so we need to use packing() + * to get it + */ + packing(rx_trailer, tstamp, 63, 0, 8, UNPACK, 0); + + *source_port = SJA1110_RX_TRAILER_SRC_PORT(last_byte); + *switch_id = SJA1110_RX_TRAILER_SWITCH_ID(last_byte); + + /* skb->len counts from skb->data, while start_of_padding + * counts from the destination MAC address. Right now skb->data + * is still as set by the DSA master, so to trim away the + * padding and trailer we need to account for the fact that + * skb->data points to skb_mac_header(skb) + ETH_HLEN. + */ + pskb_trim_rcsum(skb, start_of_padding - ETH_HLEN); + /* Trap-to-host frame, no timestamp trailer */ + } else { + *source_port = SJA1110_RX_HEADER_SRC_PORT(rx_header); + *switch_id = SJA1110_RX_HEADER_SWITCH_ID(rx_header); + } + + /* Advance skb->data past the DSA header */ + skb_pull_rcsum(skb, SJA1110_HEADER_LEN); + + /* Remove the DSA header */ + memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - SJA1110_HEADER_LEN, + 2 * ETH_ALEN); + + /* With skb->data in its final place, update the MAC header + * so that eth_hdr() continues to works properly. + */ + skb_set_mac_header(skb, -ETH_HLEN); + + return skb; +} + +static struct sk_buff *sja1110_rcv(struct sk_buff *skb, + struct net_device *netdev, + struct packet_type *pt) +{ + int source_port = -1, switch_id = -1, subvlan = 0; + + skb->offload_fwd_mark = 1; + + if (sja1110_skb_has_inband_control_extension(skb)) { + skb = sja1110_rcv_inband_control_extension(skb, &source_port, + &switch_id); + if (!skb) + return NULL; + } + + /* Packets with in-band control extensions might still have RX VLANs */ + if (likely(sja1105_skb_has_tag_8021q(skb))) + dsa_8021q_rcv(skb, &source_port, &switch_id, &subvlan); + + skb->dev = dsa_master_find_slave(netdev, switch_id, source_port); + if (!skb->dev) { + netdev_warn(netdev, + "Couldn't decode source port %d and switch id %d\n", + source_port, switch_id); + return NULL; + } + + if (subvlan) + sja1105_decode_subvlan(skb, subvlan); + + return skb; +} + static void sja1105_flow_dissect(const struct sk_buff *skb, __be16 *proto, int *offset) { @@ -343,6 +525,20 @@ static void sja1105_flow_dissect(const struct sk_buff *skb, __be16 *proto, dsa_tag_generic_flow_dissect(skb, proto, offset); } +static void sja1110_flow_dissect(const struct sk_buff *skb, __be16 *proto, + int *offset) +{ + /* Management frames have 2 DSA tags on RX, so the needed_headroom we + * declared is fine for the generic dissector adjustment procedure. + */ + if (unlikely(sja1105_is_link_local(skb))) + return dsa_tag_generic_flow_dissect(skb, proto, offset); + + /* For the rest, there is a single DSA tag, the tag_8021q one */ + *offset = VLAN_HLEN; + *proto = ((__be16 *)skb->data)[(VLAN_HLEN / 2) - 1]; +} + static const struct dsa_device_ops sja1105_netdev_ops = { .name = "sja1105", .proto = DSA_TAG_PROTO_SJA1105, @@ -354,7 +550,28 @@ static const struct dsa_device_ops sja1105_netdev_ops = { .promisc_on_master = true, }; -MODULE_LICENSE("GPL v2"); +DSA_TAG_DRIVER(sja1105_netdev_ops); MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_SJA1105); -module_dsa_tag_driver(sja1105_netdev_ops); +static const struct dsa_device_ops sja1110_netdev_ops = { + .name = "sja1110", + .proto = DSA_TAG_PROTO_SJA1110, + .xmit = sja1110_xmit, + .rcv = sja1110_rcv, + .filter = sja1105_filter, + .flow_dissect = sja1110_flow_dissect, + .needed_headroom = SJA1110_HEADER_LEN + VLAN_HLEN, + .needed_tailroom = SJA1110_RX_TRAILER_LEN + SJA1110_MAX_PADDING_LEN, +}; + +DSA_TAG_DRIVER(sja1110_netdev_ops); +MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_SJA1110); + +static struct dsa_tag_driver *sja1105_tag_driver_array[] = { + &DSA_TAG_DRIVER_NAME(sja1105_netdev_ops), + &DSA_TAG_DRIVER_NAME(sja1110_netdev_ops), +}; + +module_dsa_tag_drivers(sja1105_tag_driver_array); + +MODULE_LICENSE("GPL v2"); From patchwork Thu Jun 10 23:26:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 459016 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD973C48BDF for ; Thu, 10 Jun 2021 23:27:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AF03E613E9 for ; Thu, 10 Jun 2021 23:27:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231216AbhFJX3t (ORCPT ); Thu, 10 Jun 2021 19:29:49 -0400 Received: from mail-ed1-f41.google.com ([209.85.208.41]:37794 "EHLO mail-ed1-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230212AbhFJX3s (ORCPT ); Thu, 10 Jun 2021 19:29:48 -0400 Received: by mail-ed1-f41.google.com with SMTP id b11so35047172edy.4 for ; Thu, 10 Jun 2021 16:27:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vWXHntt6+SuAHiwSo1bFtrEltaRyItVNgpxN5V2EuXM=; b=Zj3PkZRA5pWYRF6SK8sXvu+rIIPJUqXWTiEEYg0ujr5yH3SGgy92aoC+f4gvkBO4x8 jgrSCcD1ACXPN+yMVw64kQgV2DtG5iywUyZ76r8MoeMRbJy5/TYbo4ICOMa2JEFh461R ucKh9pxry3k+MvW4GWzbHHLnUvKnDw64LB2KScnorwYwSFmjHZbT+TfGL6kbHI8HSfUk BIVCATXcD+KyJAqcRTpuaaK0/fANNWJR7s9T52e4UrAMM42nlM6jNFVNmY+XyS04gHal ZMkkYnTyl26rKOHy6tXGysRzlHQn/2iwkMz0ZBL7MddBojj5jYJbQSjwCRR+kKjAbhw6 dZXA== 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:mime-version:content-transfer-encoding; bh=vWXHntt6+SuAHiwSo1bFtrEltaRyItVNgpxN5V2EuXM=; b=kyQQG7pwM7EOoNqng44kx3s+WS1zuM+dQ19hdkjsLd/AJmX8w2vQcCZKlO+F8P6k1J WlMKUSAFra67upPYezOuKnAbAGmJgycL+IGmZo1Tz8FTKbc1zeE22TcFn9+naPy6MO5g J3vwK1NsepyKrDEpQXadokx0LnvFAW2eHZymLmFOaWScHJsfstz2VBGShxA6oDSeNcsg Tm+sxV5phvJU6lxicE7dGnzJdg2rdRoNgWuRrmKzpFo1mvyVogs/5rMXawtYlW+D7tsS YlnnJl2+mtL7yMsDo7sg56R7YAC3CFyD/3UPV+/0rMkD1anOU5KtjQLhSfcbov3AGFq8 NoHQ== X-Gm-Message-State: AOAM530FfTitlG4lCccKVlJ3Xq+hkc1eH4NQSpIprSuyQExXiQ6jUBF/ KdYt88sjZZ2AgPytXk1GaFU= X-Google-Smtp-Source: ABdhPJxe80ST95R7vhULrWRZGhtaqaT9Lqu7NciK8ZkrzEh/MntNXnIJDY8ZSYmeYjWobpIBy3FbNA== X-Received: by 2002:aa7:dd14:: with SMTP id i20mr881740edv.110.1623367611240; Thu, 10 Jun 2021 16:26:51 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id j22sm1534187ejt.11.2021.06.10.16.26.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:26:51 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Richard Cochran , Vladimir Oltean Subject: [PATCH v2 net-next 09/10] net: dsa: sja1105: add the RX timestamping procedure for SJA1110 Date: Fri, 11 Jun 2021 02:26:28 +0300 Message-Id: <20210610232629.1948053-10-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610232629.1948053-1-olteanv@gmail.com> References: <20210610232629.1948053-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean This is really easy, since the full RX timestamp is in the DSA trailer and the tagger code transfers it to SJA1105_SKB_CB(skb)->tstamp, we just need to move it to the skb shared info region. This is as opposed to SJA1105, where the RX timestamp was received in a meta frame (so there needed to be a state machine to pair the 2 packets) and the timestamp was partial (so the packet, once matched with its timestamp, needed to be added to an RX timestamping queue where the PTP aux worker would reconstruct that timestamp). Signed-off-by: Vladimir Oltean --- v1->v2: none drivers/net/dsa/sja1105/sja1105.h | 1 + drivers/net/dsa/sja1105/sja1105_ptp.c | 26 +++++++++++++++++++++++--- drivers/net/dsa/sja1105/sja1105_ptp.h | 6 ++++++ drivers/net/dsa/sja1105/sja1105_spi.c | 10 ++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index fcba65719267..f1bf290cc8a4 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -131,6 +131,7 @@ struct sja1105_info { const unsigned char *addr, u16 vid); void (*ptp_cmd_packing)(u8 *buf, struct sja1105_ptp_cmd *cmd, enum packing_op op); + bool (*rxtstamp)(struct dsa_switch *ds, int port, struct sk_buff *skb); int (*clocking_setup)(struct sja1105_private *priv); int (*pcs_mdio_read)(struct mii_bus *bus, int phy, int reg); int (*pcs_mdio_write)(struct mii_bus *bus, int phy, int reg, u16 val); diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c index dea82f8a40c4..62fe05b4cb60 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.c +++ b/drivers/net/dsa/sja1105/sja1105_ptp.c @@ -413,9 +413,7 @@ static long sja1105_rxtstamp_work(struct ptp_clock_info *ptp) return -1; } -/* Called from dsa_skb_defer_rx_timestamp */ -bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port, - struct sk_buff *skb, unsigned int type) +bool sja1105_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb) { struct sja1105_private *priv = ds->priv; struct sja1105_ptp_data *ptp_data = &priv->ptp_data; @@ -431,6 +429,28 @@ bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port, return true; } +bool sja1110_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb) +{ + struct skb_shared_hwtstamps *shwt = skb_hwtstamps(skb); + u64 ts = SJA1105_SKB_CB(skb)->tstamp; + + *shwt = (struct skb_shared_hwtstamps) {0}; + + shwt->hwtstamp = ns_to_ktime(sja1105_ticks_to_ns(ts)); + + /* Don't defer */ + return false; +} + +/* Called from dsa_skb_defer_rx_timestamp */ +bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port, + struct sk_buff *skb, unsigned int type) +{ + struct sja1105_private *priv = ds->priv; + + return priv->info->rxtstamp(ds, port, skb); +} + /* Called from dsa_skb_tx_timestamp. This callback is just to clone * the skb and have it available in SJA1105_SKB_CB in the .port_deferred_xmit * callback, where we will timestamp it synchronously. diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.h b/drivers/net/dsa/sja1105/sja1105_ptp.h index 34f97f58a355..bf0c4f1dfed7 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.h +++ b/drivers/net/dsa/sja1105/sja1105_ptp.h @@ -122,6 +122,9 @@ int __sja1105_ptp_adjtime(struct dsa_switch *ds, s64 delta); int sja1105_ptp_commit(struct dsa_switch *ds, struct sja1105_ptp_cmd *cmd, sja1105_spi_rw_mode_t rw); +bool sja1105_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); +bool sja1110_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); + #else struct sja1105_ptp_cmd; @@ -184,6 +187,9 @@ static inline int sja1105_ptp_commit(struct dsa_switch *ds, #define sja1105_hwtstamp_set NULL +#define sja1105_rxtstamp NULL +#define sja1110_rxtstamp NULL + #endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */ #endif /* _SJA1105_PTP_H */ diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 0d4158fdeec0..47b2b5451ba0 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -583,6 +583,7 @@ const struct sja1105_info sja1105e_info = { .fdb_add_cmd = sja1105et_fdb_add, .fdb_del_cmd = sja1105et_fdb_del, .ptp_cmd_packing = sja1105et_ptp_cmd_packing, + .rxtstamp = sja1105_rxtstamp, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105et_regs, .port_speed = { @@ -615,6 +616,7 @@ const struct sja1105_info sja1105t_info = { .fdb_add_cmd = sja1105et_fdb_add, .fdb_del_cmd = sja1105et_fdb_del, .ptp_cmd_packing = sja1105et_ptp_cmd_packing, + .rxtstamp = sja1105_rxtstamp, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105et_regs, .port_speed = { @@ -648,6 +650,7 @@ const struct sja1105_info sja1105p_info = { .fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .rxtstamp = sja1105_rxtstamp, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105pqrs_regs, .port_speed = { @@ -681,6 +684,7 @@ const struct sja1105_info sja1105q_info = { .fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .rxtstamp = sja1105_rxtstamp, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105pqrs_regs, .port_speed = { @@ -714,6 +718,7 @@ const struct sja1105_info sja1105r_info = { .fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .rxtstamp = sja1105_rxtstamp, .clocking_setup = sja1105_clocking_setup, .pcs_mdio_read = sja1105_pcs_mdio_read, .pcs_mdio_write = sja1105_pcs_mdio_write, @@ -751,6 +756,7 @@ const struct sja1105_info sja1105s_info = { .fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .rxtstamp = sja1105_rxtstamp, .clocking_setup = sja1105_clocking_setup, .pcs_mdio_read = sja1105_pcs_mdio_read, .pcs_mdio_write = sja1105_pcs_mdio_write, @@ -788,6 +794,7 @@ const struct sja1105_info sja1110a_info = { .fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .rxtstamp = sja1110_rxtstamp, .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, @@ -837,6 +844,7 @@ const struct sja1105_info sja1110b_info = { .fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .rxtstamp = sja1110_rxtstamp, .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, @@ -886,6 +894,7 @@ const struct sja1105_info sja1110c_info = { .fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .rxtstamp = sja1110_rxtstamp, .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, @@ -935,6 +944,7 @@ const struct sja1105_info sja1110d_info = { .fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .rxtstamp = sja1110_rxtstamp, .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, From patchwork Thu Jun 10 23:26:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 459017 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6587AC48BDF for ; Thu, 10 Jun 2021 23:27:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4ECA2613E9 for ; Thu, 10 Jun 2021 23:27:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231210AbhFJX3G (ORCPT ); Thu, 10 Jun 2021 19:29:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51984 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231180AbhFJX3E (ORCPT ); Thu, 10 Jun 2021 19:29:04 -0400 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 947C2C0617AE for ; Thu, 10 Jun 2021 16:26:53 -0700 (PDT) Received: by mail-ej1-x631.google.com with SMTP id h24so1681912ejy.2 for ; Thu, 10 Jun 2021 16:26:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=z1U9ZrmyPCyzwpDSrnx1UvFvJVk+rrmOuINXczFJEpk=; b=R0sHwBMANPp2Zyi27nPcPn1gVvXMKaE1MrDbRQXAyDCahbeNfJb18yKOrpDWSZlAAR 9hlrUUFJsTeV7tvErUKRP0lfh2J3SfSnvF2xLbAl2kPAake7kVGvc0zoMQDcaCoY24XS wrdyFjuQWVxPMdgwkGtA7uKHe1HtLW6e0HxlGwWYCgnU3yArIVr0eQS+QhTdIxAp3ik9 gztJVjKe/laqsuoAPxV6MWcQO3F2AgZJItFs6jvxLJak8PdS4BCUTj5KG0UjIkoOH8A7 Lralmi0RGdkfgHbE47xeur+kQg3V3FdCDzSuXsBC5+U6W1lSy6rZoM/uSjKEI2x4Giqu 3wxA== 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:mime-version:content-transfer-encoding; bh=z1U9ZrmyPCyzwpDSrnx1UvFvJVk+rrmOuINXczFJEpk=; b=WImXP0lOGtX1o8BJ2aSdOzcNOIO+BGC/nlp1rEFJ2LyGuztcKaTyYPNzFqbro77RAS 4BJhakdM07bsTSa/Yp8t5dO8SRQFEXQRf5bPqQxW0O9uodPJcdYf/AjixPlV8SKoaP7B MDL7YoOTt4msVsTB0FZVSpXcMPI7PtOvkbqo7iD44ZoXtjyNob/nqg9mi6HYo1+OJmT5 sr3mlfeg4cRVPm349m/2EDoYVDoUeYjvEriQtG4sZ8hTefmGDPkd/pc+MjhfWqHLJtWe bmteeikdQB9d0c6ndcYVxdK1nf2j8firQjOk2scpEFrxfp98gsvR7T5Ia2GOL+xZwoHx JoKA== X-Gm-Message-State: AOAM533zI2M1JW+YdYBALaeHVE0pH3omjXMRHXGyPFgP+sFDOo8e1UYi XMOufU8TrhH1dDAA1BmJibU= X-Google-Smtp-Source: ABdhPJwvau8LsFoCoexeU26yk+QUVjaA8jMpL6C88P1TJPmc8luuBzb44WZL2Zei7qyV+WUCS23bjQ== X-Received: by 2002:a17:907:2cf6:: with SMTP id hz22mr843346ejc.320.1623367612109; Thu, 10 Jun 2021 16:26:52 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id j22sm1534187ejt.11.2021.06.10.16.26.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 16:26:51 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Richard Cochran , Vladimir Oltean Subject: [PATCH v2 net-next 10/10] net: dsa: sja1105: implement TX timestamping for SJA1110 Date: Fri, 11 Jun 2021 02:26:29 +0300 Message-Id: <20210610232629.1948053-11-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610232629.1948053-1-olteanv@gmail.com> References: <20210610232629.1948053-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean The TX timestamping procedure for SJA1105 is a bit unconventional because the transmit procedure itself is unconventional. Control packets (and therefore PTP as well) are transmitted to a specific port in SJA1105 using "management routes" which must be written over SPI to the switch. These are one-shot rules that match by destination MAC address on traffic coming from the CPU port, and select the precise destination port for that packet. So to transmit a packet from NET_TX softirq context, we actually need to defer to a process context so that we can perform that SPI write before we send the packet. The DSA master dev_queue_xmit() runs in process context, and we poll until the switch confirms it took the TX timestamp, then we annotate the skb clone with that TX timestamp. This is why the sja1105 driver does not need an skb queue for TX timestamping. But the SJA1110 is a bit (not much!) more conventional, and you can request 2-step TX timestamping through the DSA header, as well as give the switch a cookie (timestamp ID) which it will give back to you when it has the timestamp. So now we do need a queue for keeping the skb clones until their TX timestamps become available. The interesting part is that the metadata frames from SJA1105 haven't disappeared completely. On SJA1105 they were used as follow-ups which contained RX timestamps, but on SJA1110 they are actually TX completion packets, which contain a variable (up to 32) array of timestamps. Why an array? Because: - not only is the TX timestamp on the egress port being communicated, but also the RX timestamp on the CPU port. Nice, but we don't care about that, so we ignore it. - because a packet could be multicast to multiple egress ports, each port takes its own timestamp, and the TX completion packet contains the individual timestamps on each port. This is unconventional because switches typically have a timestamping FIFO and raise an interrupt, but this one doesn't. So the tagger needs to detect and parse meta frames, and call into the main switch driver, which pairs the timestamps with the skbs in the TX timestamping queue which are waiting for one. Signed-off-by: Vladimir Oltean --- v1->v2: export the sja1110_process_meta_tstamp symbol to avoid build errors as module drivers/net/dsa/sja1105/sja1105.h | 1 + drivers/net/dsa/sja1105/sja1105_ptp.c | 69 +++++++++++++++++++++++++++ drivers/net/dsa/sja1105/sja1105_ptp.h | 7 +++ drivers/net/dsa/sja1105/sja1105_spi.c | 4 ++ include/linux/dsa/sja1105.h | 23 +++++++++ net/dsa/tag_sja1105.c | 52 ++++++++++++++++++++ 6 files changed, 156 insertions(+) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index f1bf290cc8a4..39124726bdd9 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -132,6 +132,7 @@ struct sja1105_info { void (*ptp_cmd_packing)(u8 *buf, struct sja1105_ptp_cmd *cmd, enum packing_op op); bool (*rxtstamp)(struct dsa_switch *ds, int port, struct sk_buff *skb); + void (*txtstamp)(struct dsa_switch *ds, int port, struct sk_buff *skb); int (*clocking_setup)(struct sja1105_private *priv); int (*pcs_mdio_read)(struct mii_bus *bus, int phy, int reg); int (*pcs_mdio_write)(struct mii_bus *bus, int phy, int reg, u16 val); diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c index 62fe05b4cb60..691f6dd7e669 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.c +++ b/drivers/net/dsa/sja1105/sja1105_ptp.c @@ -79,6 +79,7 @@ static int sja1105_change_rxtstamping(struct sja1105_private *priv, priv->tagger_data.stampable_skb = NULL; } ptp_cancel_worker_sync(ptp_data->clock); + skb_queue_purge(&ptp_data->skb_txtstamp_queue); skb_queue_purge(&ptp_data->skb_rxtstamp_queue); return sja1105_static_config_reload(priv, SJA1105_RX_HWTSTAMPING); @@ -451,6 +452,67 @@ bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port, return priv->info->rxtstamp(ds, port, skb); } +void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, u8 ts_id, + enum sja1110_meta_tstamp dir, u64 tstamp) +{ + struct sja1105_private *priv = ds->priv; + struct sja1105_ptp_data *ptp_data = &priv->ptp_data; + struct sk_buff *skb, *skb_tmp, *skb_match = NULL; + struct skb_shared_hwtstamps shwt = {0}; + + /* We don't care about RX timestamps on the CPU port */ + if (dir == SJA1110_META_TSTAMP_RX) + return; + + spin_lock(&ptp_data->skb_txtstamp_queue.lock); + + skb_queue_walk_safe(&ptp_data->skb_txtstamp_queue, skb, skb_tmp) { + if (SJA1105_SKB_CB(skb)->ts_id != ts_id) + continue; + + __skb_unlink(skb, &ptp_data->skb_txtstamp_queue); + skb_match = skb; + + break; + } + + spin_unlock(&ptp_data->skb_txtstamp_queue.lock); + + if (WARN_ON(!skb_match)) + return; + + shwt.hwtstamp = ns_to_ktime(sja1105_ticks_to_ns(tstamp)); + skb_complete_tx_timestamp(skb_match, &shwt); +} +EXPORT_SYMBOL_GPL(sja1110_process_meta_tstamp); + +/* In addition to cloning the skb which is done by the common + * sja1105_port_txtstamp, we need to generate a timestamp ID and save the + * packet to the TX timestamping queue. + */ +void sja1110_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb) +{ + struct sk_buff *clone = SJA1105_SKB_CB(skb)->clone; + struct sja1105_private *priv = ds->priv; + struct sja1105_ptp_data *ptp_data = &priv->ptp_data; + struct sja1105_port *sp = &priv->ports[port]; + u8 ts_id; + + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + + spin_lock(&sp->data->meta_lock); + + ts_id = sp->data->ts_id; + /* Deal automatically with 8-bit wraparound */ + sp->data->ts_id++; + + SJA1105_SKB_CB(clone)->ts_id = ts_id; + + spin_unlock(&sp->data->meta_lock); + + skb_queue_tail(&ptp_data->skb_txtstamp_queue, clone); +} + /* Called from dsa_skb_tx_timestamp. This callback is just to clone * the skb and have it available in SJA1105_SKB_CB in the .port_deferred_xmit * callback, where we will timestamp it synchronously. @@ -469,6 +531,9 @@ void sja1105_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb) return; SJA1105_SKB_CB(skb)->clone = clone; + + if (priv->info->txtstamp) + priv->info->txtstamp(ds, port, skb); } static int sja1105_ptp_reset(struct dsa_switch *ds) @@ -885,7 +950,10 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds) .n_per_out = 1, }; + /* Only used on SJA1105 */ skb_queue_head_init(&ptp_data->skb_rxtstamp_queue); + /* Only used on SJA1110 */ + skb_queue_head_init(&ptp_data->skb_txtstamp_queue); spin_lock_init(&tagger_data->meta_lock); ptp_data->clock = ptp_clock_register(&ptp_data->caps, ds->dev); @@ -910,6 +978,7 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds) del_timer_sync(&ptp_data->extts_timer); ptp_cancel_worker_sync(ptp_data->clock); + skb_queue_purge(&ptp_data->skb_txtstamp_queue); skb_queue_purge(&ptp_data->skb_rxtstamp_queue); ptp_clock_unregister(ptp_data->clock); ptp_data->clock = NULL; diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.h b/drivers/net/dsa/sja1105/sja1105_ptp.h index bf0c4f1dfed7..3c874bb4c17b 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.h +++ b/drivers/net/dsa/sja1105/sja1105_ptp.h @@ -75,7 +75,12 @@ struct sja1105_ptp_cmd { struct sja1105_ptp_data { struct timer_list extts_timer; + /* Used only on SJA1105 to reconstruct partial timestamps */ struct sk_buff_head skb_rxtstamp_queue; + /* Used on SJA1110 where meta frames are generated only for + * 2-step TX timestamps + */ + struct sk_buff_head skb_txtstamp_queue; struct ptp_clock_info caps; struct ptp_clock *clock; struct sja1105_ptp_cmd cmd; @@ -124,6 +129,7 @@ int sja1105_ptp_commit(struct dsa_switch *ds, struct sja1105_ptp_cmd *cmd, bool sja1105_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); bool sja1110_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); +void sja1110_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); #else @@ -189,6 +195,7 @@ static inline int sja1105_ptp_commit(struct dsa_switch *ds, #define sja1105_rxtstamp NULL #define sja1110_rxtstamp NULL +#define sja1110_txtstamp NULL #endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */ diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 47b2b5451ba0..7c493c6a839d 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -795,6 +795,7 @@ const struct sja1105_info sja1110a_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .rxtstamp = sja1110_rxtstamp, + .txtstamp = sja1110_txtstamp, .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, @@ -845,6 +846,7 @@ const struct sja1105_info sja1110b_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .rxtstamp = sja1110_rxtstamp, + .txtstamp = sja1110_txtstamp, .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, @@ -895,6 +897,7 @@ const struct sja1105_info sja1110c_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .rxtstamp = sja1110_rxtstamp, + .txtstamp = sja1110_txtstamp, .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, @@ -945,6 +948,7 @@ const struct sja1105_info sja1110d_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .rxtstamp = sja1110_rxtstamp, + .txtstamp = sja1110_txtstamp, .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h index b02cf7b515ae..b6089b88314c 100644 --- a/include/linux/dsa/sja1105.h +++ b/include/linux/dsa/sja1105.h @@ -45,11 +45,14 @@ struct sja1105_tagger_data { */ spinlock_t meta_lock; unsigned long state; + u8 ts_id; }; struct sja1105_skb_cb { struct sk_buff *clone; u64 tstamp; + /* Only valid for packets cloned for 2-step TX timestamping */ + u8 ts_id; }; #define SJA1105_SKB_CB(skb) \ @@ -66,4 +69,24 @@ struct sja1105_port { u16 xmit_tpid; }; +enum sja1110_meta_tstamp { + SJA1110_META_TSTAMP_TX = 0, + SJA1110_META_TSTAMP_RX = 1, +}; + +#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) + +void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, u8 ts_id, + enum sja1110_meta_tstamp dir, u64 tstamp); + +#else + +static inline void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, + u8 ts_id, enum sja1110_meta_tstamp dir, + u64 tstamp) +{ +} + +#endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */ + #endif /* _NET_DSA_SJA1105_H */ diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c index 37e1d64e07c6..9c2df9ece01b 100644 --- a/net/dsa/tag_sja1105.c +++ b/net/dsa/tag_sja1105.c @@ -25,6 +25,9 @@ #define SJA1110_RX_TRAILER_SWITCH_ID(x) (((x) & GENMASK(7, 4)) >> 4) #define SJA1110_RX_TRAILER_SRC_PORT(x) ((x) & GENMASK(3, 0)) +/* Meta frame format (for 2-step TX timestamps) */ +#define SJA1110_RX_HEADER_N_TS(x) (((x) & GENMASK(8, 4)) >> 4) + /* TX header */ #define SJA1110_TX_HEADER_UPDATE_TC BIT(14) #define SJA1110_TX_HEADER_TAKE_TS BIT(13) @@ -43,6 +46,8 @@ #define SJA1110_TX_TRAILER_SWITCHID(x) (((x) << 12) & GENMASK(15, 12)) #define SJA1110_TX_TRAILER_DESTPORTS(x) (((x) << 1) & GENMASK(11, 1)) +#define SJA1110_META_TSTAMP_SIZE 10 + #define SJA1110_HEADER_LEN 4 #define SJA1110_RX_TRAILER_LEN 13 #define SJA1110_TX_TRAILER_LEN 4 @@ -184,6 +189,7 @@ static struct sk_buff *sja1105_xmit(struct sk_buff *skb, static struct sk_buff *sja1110_xmit(struct sk_buff *skb, struct net_device *netdev) { + struct sk_buff *clone = SJA1105_SKB_CB(skb)->clone; struct dsa_port *dp = dsa_slave_to_port(netdev); u16 tx_vid = dsa_8021q_tx_vid(dp->ds, dp->index); u16 queue_mapping = skb_get_queue_mapping(skb); @@ -221,6 +227,12 @@ static struct sk_buff *sja1110_xmit(struct sk_buff *skb, *tx_trailer = cpu_to_be32(SJA1110_TX_TRAILER_PRIO(pcp) | SJA1110_TX_TRAILER_SWITCHID(dp->ds->index) | SJA1110_TX_TRAILER_DESTPORTS(BIT(dp->index))); + if (clone) { + u8 ts_id = SJA1105_SKB_CB(clone)->ts_id; + + *tx_header |= htons(SJA1110_TX_HEADER_TAKE_TS); + *tx_trailer |= cpu_to_be32(SJA1110_TX_TRAILER_TSTAMP_ID(ts_id)); + } return skb; } @@ -423,6 +435,43 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb, is_meta); } +static struct sk_buff *sja1110_rcv_meta(struct sk_buff *skb, u16 rx_header) +{ + int switch_id = SJA1110_RX_HEADER_SWITCH_ID(rx_header); + int n_ts = SJA1110_RX_HEADER_N_TS(rx_header); + struct net_device *master = skb->dev; + struct dsa_port *cpu_dp; + u8 *buf = skb->data + 2; + struct dsa_switch *ds; + int i; + + cpu_dp = master->dsa_ptr; + ds = dsa_switch_find(cpu_dp->dst->index, switch_id); + if (!ds) { + net_err_ratelimited("%s: cannot find switch id %d\n", + master->name, switch_id); + return NULL; + } + + for (i = 0; i <= n_ts; i++) { + u8 ts_id, source_port, dir; + u64 tstamp; + + ts_id = buf[0]; + source_port = (buf[1] & GENMASK(7, 4)) >> 4; + dir = (buf[1] & BIT(3)) >> 3; + tstamp = be64_to_cpu(*(__be64 *)(buf + 2)); + + sja1110_process_meta_tstamp(ds, source_port, ts_id, dir, + tstamp); + + buf += SJA1110_META_TSTAMP_SIZE; + } + + /* Discard the meta frame, we've consumed the timestamps it contained */ + return NULL; +} + static struct sk_buff *sja1110_rcv_inband_control_extension(struct sk_buff *skb, int *source_port, int *switch_id) @@ -439,6 +488,9 @@ static struct sk_buff *sja1110_rcv_inband_control_extension(struct sk_buff *skb, */ rx_header = ntohs(*(__be16 *)skb->data); + if (rx_header & SJA1110_RX_HEADER_IS_METADATA) + return sja1110_rcv_meta(skb, rx_header); + /* Timestamp frame, we have a trailer */ if (rx_header & SJA1110_RX_HEADER_HAS_TRAILER) { int start_of_padding = SJA1110_RX_HEADER_TRAILER_POS(rx_header);