From patchwork Thu Jun 10 17:34:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 459046 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 6B768C47094 for ; Thu, 10 Jun 2021 17:35:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4BF75613E1 for ; Thu, 10 Jun 2021 17:35:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230265AbhFJRg6 (ORCPT ); Thu, 10 Jun 2021 13:36:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59116 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229802AbhFJRg5 (ORCPT ); Thu, 10 Jun 2021 13:36:57 -0400 Received: from mail-ej1-x630.google.com (mail-ej1-x630.google.com [IPv6:2a00:1450:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AAAB7C061760 for ; Thu, 10 Jun 2021 10:35:00 -0700 (PDT) Received: by mail-ej1-x630.google.com with SMTP id k25so422500eja.9 for ; Thu, 10 Jun 2021 10:35:00 -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=by48++3AxiExmswbyD3pG9IXGFwzf6C3FctQPsWJ55c=; b=vTpuuBnzeN2ZslCSb1IlgPYL9nQmNG7kKToRPnrBeArmVvWgFap2Ite6NAUv5qT+c+ YatJFg1/V0h7PpZ9Me5J5bUAVOdodeqJqV4IKjVXEBOSaoeVgv4cgYZkLbC3GQwaWgHe 3Vld/u661Rjp/fYGZNC+ehtTA/qpPMlJOriix3ELWx1Fg/bcpV2wwFZKOspad/35wizc Ndm945t6MdqouZUa2O1hm9KQMkKAwGOe4fmuSwgRppRQc4FsO1/Apd/Be5T9Yg++7YR0 WkKMM5X1vEIebdba5MeEvT/FIYTRjOB4WGikCPB7NxVOoyDil7QBRXK+BjQgbg3efMQ7 MrmQ== 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=by48++3AxiExmswbyD3pG9IXGFwzf6C3FctQPsWJ55c=; b=AOJuee99zydJ/DVZjnlTWG1SmLXMo000U9FPQDbfwglx4deDlmujVs5lcPMz++dYRz wyrlVSot8Q39kiFZ9nPMTTjTpvuEDgXVPeLS2EYoYC78yjxb8YR0Vo/ipoVpkQ4Kz8dI dvjP7HFzQQHNAnjTV8DNT77EpBvTs38jW1fzQhjYlsAk392SNtK1lgnSVqJXEa43l9oU vKJeo8lSMLdwk1KNniCvLP8gfUjDVZdYuy74tZBGMbTDi4BtAYQM7ztaUks5GdL6YlW1 +oHa6RwIIZ8PShOWDfqtJ4zEh8LW9n3uKM1/OeXfd7njDh1x2sQfUf8Y6DKi92dMBk+8 b1rg== X-Gm-Message-State: AOAM530lgo/5qz3KW5/s2P3obQnLo5ROlqEM+D8Ne93WsAKYlrPjyZy8 WuKNtg70l2VIQi30Wq4DoKw= X-Google-Smtp-Source: ABdhPJzEg1NnzTszwinkN+hKSP+jTTcym0AQMSNIIBNaJb2LPX4WEC1TBFY0CLL/9Xk/G2rw+E8GxA== X-Received: by 2002:a17:906:3181:: with SMTP id 1mr738421ejy.36.1623346499124; Thu, 10 Jun 2021 10:34:59 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id g17sm1789595edp.14.2021.06.10.10.34.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 10:34:58 -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 net-next 01/10] net: dsa: sja1105: enable the TTEthernet engine on SJA1110 Date: Thu, 10 Jun 2021 20:34:16 +0300 Message-Id: <20210610173425.1791379-2-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610173425.1791379-1-olteanv@gmail.com> References: <20210610173425.1791379-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 --- 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 3b031864ad74..de132a7a4a7a 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -673,6 +673,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 17:34:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 458320 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 01BC5C48BDF for ; Thu, 10 Jun 2021 17:35:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DF189613E9 for ; Thu, 10 Jun 2021 17:35:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230401AbhFJRg7 (ORCPT ); Thu, 10 Jun 2021 13:36:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230377AbhFJRg6 (ORCPT ); Thu, 10 Jun 2021 13:36:58 -0400 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B28DFC061760 for ; Thu, 10 Jun 2021 10:35:01 -0700 (PDT) Received: by mail-ed1-x52e.google.com with SMTP id ba2so32252501edb.2 for ; Thu, 10 Jun 2021 10:35:01 -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=R35MWfVdpbq1gHwH4NrQr70JsgBdse7X0L8WNH74fR4=; b=TLeVPCko9Pcc8BW18fmIiVPyKe3HrA7/YFXCWDKuZALz99PvbjrOiincZcD6RlwYZG s6+rK7az1EsJbPMpCnejEti/z5hm2yf5rPr2Q+h6GJnyvxJhN5+d78AjKkBt0lUOnCGB DdxM8fgdB95tBZPDLirZISOrqP3nfS6EkrU2mQYFm2xnk/dwnrH8DHgYCWSYh3TtlYRv NCDLka0zR40WsDkWxz71f+LcNCtTfkTH3dDTyTx15DcB5Ki47uVarIV8duc5907MzHUH JxmblPuZBAmM0XFS90O/84uLfxjpISUzhnaJMF/5zAIEYOK/v/DQAUiE8ac1ht8KgBiO J9xQ== 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=R35MWfVdpbq1gHwH4NrQr70JsgBdse7X0L8WNH74fR4=; b=lPWWLvWHwP/To9FOy154n8RXk5NK8Fsqij+rh9clOL5rOB9pCM2QC/mP25mogTWlbx 576CEXlllrduDt7AxNLDSTkMA23t38uGjNnhzCLc3sYnQ+7+C8wTGSlNreXSIs6+PgT5 AGlc/1aGAUQ1gl9rihFWUUPCjDsUY6j+q3J4IwDV8et7GJZkxiZvarcfyny+yPbvcBEm fvTWkdD08kl90dDAlONbfbAil7nRm92zWBYM08eX4i4JNCgifuAyCKl+5y8yxMrr8A2F dCXH1qI+HHBC45oHTW095kwr4kW7Hn24QFX2hnkFXbHASMQ9+NnzXPLuhXeieLJ+YXPE SY3Q== X-Gm-Message-State: AOAM532ghgop56pGy22xarIljkmZGv/l7C4tu3L8khjHM6kHkrbIIkkW loDzw435R4lDyzshEbgI5YmqRK2HP0M= X-Google-Smtp-Source: ABdhPJz+YGiRLh3gyzLCvlpaaW4GKuz8zqGvmzGvKxN0qhV1VCkmXVRjQvRpFr0xyDhD23w3+99zsQ== X-Received: by 2002:aa7:c445:: with SMTP id n5mr657185edr.64.1623346500227; Thu, 10 Jun 2021 10:35:00 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id g17sm1789595edp.14.2021.06.10.10.34.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 10:34:59 -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 net-next 02/10] net: dsa: sja1105: allow RX timestamps to be taken on all ports for SJA1110 Date: Thu, 10 Jun 2021 20:34:17 +0300 Message-Id: <20210610173425.1791379-3-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610173425.1791379-1-olteanv@gmail.com> References: <20210610173425.1791379-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 --- 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 f762f5488a76..4d192331754c 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -109,6 +109,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 de132a7a4a7a..850bbc793369 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -654,14 +654,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, @@ -676,6 +668,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; @@ -701,12 +694,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 54ecb5565761..e6c2a37aa617 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -763,6 +763,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, @@ -808,6 +809,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, @@ -853,6 +855,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, @@ -898,6 +901,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 17:34:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 458315 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 52FEEC47094 for ; Thu, 10 Jun 2021 17:36:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3B2B0613E3 for ; Thu, 10 Jun 2021 17:36:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231246AbhFJRh7 (ORCPT ); Thu, 10 Jun 2021 13:37:59 -0400 Received: from mail-ed1-f44.google.com ([209.85.208.44]:38840 "EHLO mail-ed1-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230051AbhFJRh6 (ORCPT ); Thu, 10 Jun 2021 13:37:58 -0400 Received: by mail-ed1-f44.google.com with SMTP id d13so20475938edt.5 for ; Thu, 10 Jun 2021 10:36:01 -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=kH6YJD/XoOCLim6QyTt5pOniDEXuTmphfPtmVeI990k=; b=TXEHU6CpFP/SE01VMz5nOlRkOjUEcYAWMNKATD5zGotjJZkYKCGX+/yHKkfi3n3f6z mMVz1dTEA75XtYZs6vCKgCkyokSxwZpnJkR1SMt84nJUIcm2mf2gXyQl56nj3vgs6J+Q KdOoX8LulQM0eP7H96aOmgi0wISwD8zVXsx/+vFb/kXyDy/atHCmFGAN12vZpA1O8Uu8 FFZvqL/H6Pkdkfp6mquQQJFpPLyAcYThWDrbfTzXD/j6fzsqB/39mSfjFwKcHmkhfIeR GsooQakDO56f6OfoNWy85fZCKiQyx7ow82Peu9eSjvKtJA3B91TT4VfA1zhhCQguqtql j68g== 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=kH6YJD/XoOCLim6QyTt5pOniDEXuTmphfPtmVeI990k=; b=qvQJb/Tbk5oVEDR8XBrNKwWeJACs6l3YdYYVmIiJWoir9ig3pZwGRvRaHlBtdrTd9t a9sscFlbhrd8L0+l7E4NKwcXKiQNzTymH2zqi036UtF1bQQ5OSKB8cIvxhZ+iu77KIZX O7CzfY9n1RlbDQ5sbZP9o0lkasxlPCf4kZjpyI4n6Up09p7dchozFXJaL1nXCunrn5c4 wCdSWhn23XIWqM/N0WQn4lKDD0ScB7L3mjpvV/QUp+d5tBMx66bcd4xKVPfBZxdI/xwv SM9xGruUF2ZZOeoSeY/3uQ2S0hiK4jHaPqZu90ZZ4KdRTUMW6kw6GnH1BFYS7H9cxGJA zcdg== X-Gm-Message-State: AOAM530qO36midhLRc0NHq/5QJF/2RKsvi9wm+PQ5qQxNf7w/GiHCyHR eqQQ8GJmtUsRRVQOGdqeJQg= X-Google-Smtp-Source: ABdhPJw473MULSAD1TKnWixIjAXqdPzdQG/qTwB4OgwwedfttV2pxnqpDZ/F1SG7xTZ3cK/b922e5g== X-Received: by 2002:a05:6402:18c:: with SMTP id r12mr655388edv.10.1623346501309; Thu, 10 Jun 2021 10:35:01 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id g17sm1789595edp.14.2021.06.10.10.35.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 10:35:00 -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 net-next 03/10] net: dsa: generalize overhead for taggers that use both headers and trailers Date: Thu, 10 Jun 2021 20:34:18 +0300 Message-Id: <20210610173425.1791379-4-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610173425.1791379-1-olteanv@gmail.com> References: <20210610173425.1791379-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 --- 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..a2787bdd057c 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 17:34:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 458314 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 2774EC47094 for ; Thu, 10 Jun 2021 17:36:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0FA2F61285 for ; Thu, 10 Jun 2021 17:36:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230356AbhFJRiO (ORCPT ); Thu, 10 Jun 2021 13:38:14 -0400 Received: from mail-ed1-f53.google.com ([209.85.208.53]:33389 "EHLO mail-ed1-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231249AbhFJRiJ (ORCPT ); Thu, 10 Jun 2021 13:38:09 -0400 Received: by mail-ed1-f53.google.com with SMTP id f5so28995074eds.0 for ; Thu, 10 Jun 2021 10:36:02 -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=bq2sTXppE3vWWf+YO0inT3m8fFWkaJHkeJaZb/ltFJc=; b=EqVeHkawKUlQeK3u4vmA8e1+lJE7dOGJmYaDuthmtkXF94DkRt2XkAFHVRnYunzm2j mFdAG3z5LLZj5d4Ai1OgTojuLDNHWwruVg59pszGyFIfZuA6ApOBwvgZOatgv4370qmt OHDq575GlDZH2AwDzeZw/N09I4WftffygPWNt9+HaI/fKHJHpwFNrKp2CtbvqrvTZq7O w1JmWvJ/y8kmzqMkeg46qoqbB8wifUrnlom1ANoOZLMlIjo/n1X3ALN1KJQ3NEOJ4REz 7vXaIXEX4Xe89Hqg/armPaQ99fNXdlhqzSKstMZGpTf0IpJe79Kfcorpb5eDAf5bRvHh 20rQ== 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=bq2sTXppE3vWWf+YO0inT3m8fFWkaJHkeJaZb/ltFJc=; b=ctWWq4L1ttnfSFmf7o//qjLn4FZFcmcicEtW/Tf8/wmLvPyA6FGMW3gmcRyf2zysVL SHyRsYNr/FB8hZI4VHP4mkfgolJQbk6MjD3t+AezXU5Tr3H/SqrobDlJ2ymo6cNeY6wf M/qG/UEzYhcKsAl5fr5yQkvdRNEeafnBzjsKaVilKpC/XV9KXXGbqz1tpWsdSN6iXyyh vlqOXbgNkl9nnisG00CzBB6kf5ysf/2jrDE26oJHBuNx/Z7go4+ApUiE58V20WKHpd+Z 5xVbZgCNxQV42DA81jirVOwVZ0tgcQs0ChjuaAhBOec7wE77mef/FneXEbymoeK4sb6y W+nA== X-Gm-Message-State: AOAM532U0kavrneFnBPv/9C/gWBBEmYbpnb1ADN5CaDxguEfHmRcskWJ T7J6eRmtPCn1XjPVjdzXz2k= X-Google-Smtp-Source: ABdhPJzqcru3GYNLjrBEGKeuvOvSahTcaipxK9+1uaj1tUHCvYm1a+wLwl5GJTF+k1OkgU14FY2Vgw== X-Received: by 2002:a50:a446:: with SMTP id v6mr634018edb.254.1623346502349; Thu, 10 Jun 2021 10:35:02 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id g17sm1789595edp.14.2021.06.10.10.35.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 10:35:02 -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 net-next 04/10] net: dsa: tag_sja1105: stop resetting network and transport headers Date: Thu, 10 Jun 2021 20:34:19 +0300 Message-Id: <20210610173425.1791379-5-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610173425.1791379-1-olteanv@gmail.com> References: <20210610173425.1791379-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 --- 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 17:34: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: 459045 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 CF827C47094 for ; Thu, 10 Jun 2021 17:35:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B9770613D0 for ; Thu, 10 Jun 2021 17:35:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230411AbhFJRhC (ORCPT ); Thu, 10 Jun 2021 13:37:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59134 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230407AbhFJRhB (ORCPT ); Thu, 10 Jun 2021 13:37:01 -0400 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C6D80C061760 for ; Thu, 10 Jun 2021 10:35:04 -0700 (PDT) Received: by mail-ed1-x533.google.com with SMTP id cb9so34042830edb.1 for ; Thu, 10 Jun 2021 10:35:04 -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=pPFtNdBfRE3W0V85CFXuPYglVMWW28G+16rA3Kbzhw0=; b=D3oPwX7wuoA0V2tluHcQFWuEPMQdyaSG/kkjhy5isYdEFJDWcB0OmTND7QY+Bh5QH5 mdj7V1OonBGNNKS0RE+Qb+CQvxAAtA6UUNMx1oymMX76LdxVIrPKwkJ2zYBb/OZRNxi2 pRTM5JoyPTMLrQBaOKI6cQqEDq6LN2s/JIvTexkAMXwcLjX/l3bj4uZGMKFSzg3OMi39 DSlYbHWhGGwWHjO+7YgAQcp3BDH/RWrbC90COAVKAgprXqWCjQ3AfzkovpoAaF3DX/co GXSumaPw5TXGBoY7XbWBysLRFroS2XDysyTDQfVOMQbXMMvV/JeBvLuFGc1hGbCYpQ56 ceeQ== 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=pPFtNdBfRE3W0V85CFXuPYglVMWW28G+16rA3Kbzhw0=; b=V71WwSUbO4HiRkW/Civu4V1FyMuOt3Ip+iR41DUVxXCw51/7t0IF8sLOO+3UOHqjs1 DzPo34bVwu6qZCczLkvyUPetXJp5iM2eppEAlqHlXsJT176xhX0aMryFvUSsoKFSjDFx iKBT0DBtwPbrhmlVCXFzQnerWx6mnBZSnGgdUysbscaQ2q5tLYiZVWq8p/bEXERzvkEz UU2GX6D6ASRsz+ep/tPsn3xD6wvMG0CYSYG5L4Y7QHElflBER80KGehuy0D+i+zyiPMZ mHsJlfAuZdDtzWotGIYlo90LNO7VsiU8jZIt1B3rfZQwbmWbYfQ3DeZv24S4IuMt2ISO jGAQ== X-Gm-Message-State: AOAM531SPoZuLPRAqyLuc3P9PekWOE/4mmetFcfYuaspUoJTpCz/kxlL SP/YahdG7CEM1TgyukDVIPU= X-Google-Smtp-Source: ABdhPJzVEuCVVT5sQoE+uvTiM/pktdFOv23oivdDxYQ6yfgtEMgdWV09R03RH8bmbub09VrVKayr4A== X-Received: by 2002:a50:cb8a:: with SMTP id k10mr585701edi.267.1623346503311; Thu, 10 Jun 2021 10:35:03 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id g17sm1789595edp.14.2021.06.10.10.35.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 10:35:02 -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 net-next 05/10] net: dsa: tag_8021q: remove shim declarations Date: Thu, 10 Jun 2021 20:34:20 +0300 Message-Id: <20210610173425.1791379-6-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610173425.1791379-1-olteanv@gmail.com> References: <20210610173425.1791379-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 --- 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 17:34: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: 459040 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 0D302C48BDF for ; Thu, 10 Jun 2021 17:36:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E78DE613D0 for ; Thu, 10 Jun 2021 17:36:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231271AbhFJRiJ (ORCPT ); Thu, 10 Jun 2021 13:38:09 -0400 Received: from mail-ej1-f41.google.com ([209.85.218.41]:39544 "EHLO mail-ej1-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231216AbhFJRiC (ORCPT ); Thu, 10 Jun 2021 13:38:02 -0400 Received: by mail-ej1-f41.google.com with SMTP id l1so443645ejb.6 for ; Thu, 10 Jun 2021 10:36:05 -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=1t3RaxyVyJVD7mirypPBdoS9B/N0JlFENjTUbHk6/1Q=; b=TT22kNvLDYwsZxVJPrDtcNGUPir0GQbTo6IKXmnHedFk4gfoSTUtTfz2igeZHSRhFh E9cNoI/qiD3JusTa639kFYf+WPsxLYmXtWZABW9KVqfWoiWAPJLnnMDy2lzh6raHFiz8 PtxBPauOSA0wwGmE7ONIatURLn7kGEI5CPX1EsSTOd9G8ie49yVY7smkImJ8bdBs6qVf 1yIPYE6s0Oxe/pdoXHRRNg+sQ2c1CwJvsqpuzO2Uk8Rm1/SX6xJtzMhmkwPXudPRWk6c wUaEQUuNOpd/bFUqDAqy7VoUHO7xnVQ3s2Y1atZ+2/lkCw6V39fgGoWswKMn0rbrKHMv aBeA== 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=1t3RaxyVyJVD7mirypPBdoS9B/N0JlFENjTUbHk6/1Q=; b=r2Hnw4runLH5zmhD39zI1xpW+TrbIXj30uY2TBpRlRRofblurNRtClXWpTgIr0jdjp OmybuONe/G3hNsZENDHqpzGQDyHXKxymAoWP8AnABOr7/DxaAtBD+GCtoZcpLSneWFDX oONM6hUP0D3VohyAVyJln4UE0eUh5f6bp8J4LAdMBzNK6E/ilPETUehD4shVZA7lAmeL bmLilKgy5KuGrhAjjGilBNKI/LYY/9MrTSDp1qi3bIUSCa+r7UMZAZSLq1bOi2/Zdb4C rVibxXoFrLPIZbSmEx4RQDdQuAnirvgF3Uo2ZXKPImgsAnxMbWqsILhYmC0e/OUSnhaV JbRQ== X-Gm-Message-State: AOAM530WALUM1IkD8/+vg3iFCmWZhf2KZ2RaSV5obtDMV9fsMhL5VE6y aH9luF2BnKdIl92Mjyl38p0= X-Google-Smtp-Source: ABdhPJxTIO5rNnyfixQhR/rG0BDGqSrev/161DNyEkyDEYbPuKQfY/eKlt842Y8i/CmLQCsKOBfLVw== X-Received: by 2002:a17:906:af85:: with SMTP id mj5mr741163ejb.352.1623346504560; Thu, 10 Jun 2021 10:35:04 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id g17sm1789595edp.14.2021.06.10.10.35.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 10:35:03 -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 net-next 06/10] net: dsa: tag_8021q: refactor RX VLAN parsing into a dedicated function Date: Thu, 10 Jun 2021 20:34:21 +0300 Message-Id: <20210610173425.1791379-7-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610173425.1791379-1-olteanv@gmail.com> References: <20210610173425.1791379-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 --- include/linux/dsa/8021q.h | 3 +++ net/dsa/tag_8021q.c | 22 ++++++++++++++++++++++ net/dsa/tag_ocelot_8021q.c | 18 ++---------------- net/dsa/tag_sja1105.c | 33 +++++++++++---------------------- 4 files changed, 38 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..74bcf48169be 100644 --- a/net/dsa/tag_8021q.c +++ b/net/dsa/tag_8021q.c @@ -471,4 +471,26 @@ 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; +} + 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 17:34: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: 458319 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 02C11C47094 for ; Thu, 10 Jun 2021 17:35:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E10F9613F1 for ; Thu, 10 Jun 2021 17:35:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230407AbhFJRhG (ORCPT ); Thu, 10 Jun 2021 13:37:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230313AbhFJRhE (ORCPT ); Thu, 10 Jun 2021 13:37:04 -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 3BA56C061760 for ; Thu, 10 Jun 2021 10:35:07 -0700 (PDT) Received: by mail-ed1-x530.google.com with SMTP id u24so33980216edy.11 for ; Thu, 10 Jun 2021 10:35:07 -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=UX3ZOrFKc9XEXKUTaY+3jPa4ybC8BGt76memUh2Ajo0=; b=qD8bYhwGbsVOJLHllI61Z/+438zCY1PGFp3E5YOjou7Mv95LlSlpqrrUjonildcASd YgAvFN4t5uIs6phhBxNC1G2y2vBJhy60rS/n78eS09MTigdPVq45NgqMMyAb0g3tAJ8A KuOz15urr7bcq2LwPnLIUW/yYMFAI12/1wK0s35B0zcYf23jSAQ5Yb+9B26vbRZPgAXJ nhIMqD5H/S8LcdLxistth5QgUQIt186VrnzJ1FBgccIupa/+ohEcGzC2giuG8ryqCQS/ UFlSEUgqJvWr3LmwEWY3KUZ07pQ//zeFjtLEQCOMIhJ/uDfkpaK4fj7myQ3eoJh5AJ0I iUGw== 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=UX3ZOrFKc9XEXKUTaY+3jPa4ybC8BGt76memUh2Ajo0=; b=fqDskRzQ2wQ4IPFJpdRte2qWg3Lp3L6OnGD80cG9huaafnNa9nPbAGrwYqRq2mbamE nDYzo/L9jLVDSWV2B24bkHu9l4dePAluYUFWlg3jMppFEEEv09AgpXWp6fPMl0BpmYhP j8Cz/oBkxbQieHfusMMsJsbgrPC5DYrZptop2Yo0HCmlWS5VZalp/2HK0meYhRH4cklH wclVRUDdb482N+xSs+uByk9PlFnmHZZtm0BvzDJxKZ7bOldoNZh87yUHsOl/CB6vbPTf 41qrG1Tt/QdW+BjABESwlgmA1b3fDZeWdPic0fqFtbl6ynsnsR0IVj6KmT3QhqJ81h4x 9w5Q== X-Gm-Message-State: AOAM531EmLbc+1Cdh8vQHZ5NdEv35sdQWh+7heB06yaKv3RBaU4KdVT9 26guulsQ/nHRgmCjnOL7W9I= X-Google-Smtp-Source: ABdhPJz3l+/ZnxxefdhyUdu2wyG/fu2qHBFFxcysq/viaXhXZdFprel1iNTIgC50VHzhCYWqtgdErw== X-Received: by 2002:a05:6402:13d7:: with SMTP id a23mr632027edx.120.1623346505710; Thu, 10 Jun 2021 10:35:05 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id g17sm1789595edp.14.2021.06.10.10.35.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 10:35:05 -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 net-next 07/10] net: dsa: sja1105: make SJA1105_SKB_CB fit a full timestamp Date: Thu, 10 Jun 2021 20:34:22 +0300 Message-Id: <20210610173425.1791379-8-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610173425.1791379-1-olteanv@gmail.com> References: <20210610173425.1791379-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 --- 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 17:34: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: 459043 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 B2E24C47094 for ; Thu, 10 Jun 2021 17:35:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9B1C7613E1 for ; Thu, 10 Jun 2021 17:35:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230434AbhFJRhU (ORCPT ); Thu, 10 Jun 2021 13:37:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231124AbhFJRhS (ORCPT ); Thu, 10 Jun 2021 13:37:18 -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 011FDC0617AE for ; Thu, 10 Jun 2021 10:35:09 -0700 (PDT) Received: by mail-ej1-x631.google.com with SMTP id ci15so413308ejc.10 for ; Thu, 10 Jun 2021 10:35:08 -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=ECuo6awgoGxEG7STkMOoveDQxxH1iM781MK8hiOUQug=; b=EzcsvZTY7iuhklE2xtvzck/YAw/RLsgiJXF35D8vv0yyL8KJu56H59xrgeLP6ilYmb uXd1n0PiksquuP3FZVNYI5zQWqcytiqgAsPtVhF7pDC0ta1KCRkQOyvuOaLtJj0Tb2WQ rHT2/vLIYJN9DCqQC9dD6SDlGhEjOKIXr7oHbgP1IKR8Rs4lvmLwcyrTJuAKpAag8ppo /GEUrbYlHtV7K4S6sbEkheOkP9Fbc+0DjEThz+gO9u/k/nR/v1eacptm6+KdOZF2wKAy NKK0QEdRDbN3riDyL3M03mxhZDFCw+3VvC/024JsNMImfjhSVWaXisNWADRgj4FkRes5 ERrg== 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=ECuo6awgoGxEG7STkMOoveDQxxH1iM781MK8hiOUQug=; b=ivmZTtXNxzbshGQPhj/k8Ov/nvpxKPRKANhDc9hiKu7lV+yxRwSUKUKCOkN4DHGz24 lf5D3cbRPXldzkHab0tRU8ac7PQCxKxzPbr8frcsCVqg2Y/L9p0kY19sRV63/MM97sIQ 9RRP5OnPPtbGge8507r0hSotJThP3PgvPvamjNfhgh3fldXPboYubyR3AQg09KzbVo8J RINBH4T0D1PtrJ1eAxBoou4rbLQdIpKZBiuAX+ZFYbw57Up6dVOaR5ck42DJF/lIXSMk G7gH0fVyjI3K4prf3FyYFWbP6QjFf4kNRBnghFuWhfT+4+5xknv0asxxQ7wZ3F4HY/cM +UhQ== X-Gm-Message-State: AOAM531Gqv9p141tTXl2RqBbqUq3nKrKGjke9JceZCHxwS79MnuifxKy hsdpo+HP0KWEYkaQd5wLmYM= X-Google-Smtp-Source: ABdhPJxVLn1+W1f83VXDN2spSCCXiyUechVLjhI2jL/dcsbwRSGYEJFgyKLbuDC5TNjXdLGYWRG2aQ== X-Received: by 2002:a17:906:e88:: with SMTP id p8mr697407ejf.105.1623346507308; Thu, 10 Jun 2021 10:35:07 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id g17sm1789595edp.14.2021.06.10.10.35.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 10:35:06 -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 net-next 08/10] net: dsa: add support for the SJA1110 native tagging protocol Date: Thu, 10 Jun 2021 20:34:23 +0300 Message-Id: <20210610173425.1791379-9-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610173425.1791379-1-olteanv@gmail.com> References: <20210610173425.1791379-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 --- 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 4d192331754c..a6d64b27e6a9 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -110,6 +110,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 850bbc793369..6e2cfbf605ef 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -667,6 +667,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; @@ -2174,7 +2176,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 e6c2a37aa617..9156f4cc11f2 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -569,6 +569,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, @@ -600,6 +601,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, @@ -631,6 +633,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, @@ -663,6 +666,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, @@ -695,6 +699,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, @@ -729,6 +734,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, @@ -762,6 +768,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, @@ -808,6 +815,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, @@ -854,6 +862,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, @@ -900,6 +909,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 17:34: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: 459042 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 7DE51C48BD1 for ; Thu, 10 Jun 2021 17:35:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 60DD761285 for ; Thu, 10 Jun 2021 17:35:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231197AbhFJRha (ORCPT ); Thu, 10 Jun 2021 13:37:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59148 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231153AbhFJRhW (ORCPT ); Thu, 10 Jun 2021 13:37:22 -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 17C60C061760 for ; Thu, 10 Jun 2021 10:35:10 -0700 (PDT) Received: by mail-ed1-x530.google.com with SMTP id t3so34005695edc.7 for ; Thu, 10 Jun 2021 10:35:10 -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=jxLh/WF1huv8WI/G2nthBCTAxv11ECLDRHuW5UnGaRA=; b=Ncob5lI6TYWLVyXsAM/FTJBcmF3MTO8vfPdHoyLYJpv+L0/WlFMcCF56D2kdJbMaAi +XLHeFN8/gyokwTvi+RPtB0BrDvQsATNEh4GL1O7MHkkQr3vfUklb/wAY7U34m0S8DiE ObKO2vqrrf6QQ6lMNnqMwzOEGlM2NVOV+JrvzpjjAedOYk7UeERXenl/mEB+AxekPVe/ onNMvsrGPBfHW5Ll9hlERmk/zzKcQFw2Jzt7LJe97iVl+HfpxTpxQaqJDZSqGbgoC8zh gRItBCKTQ7nhxLYpFbAoJwsVVukIeFVbWtLFvlP0TYcEq3c17ssky/N8tksg6i9TAfOC P/KQ== 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=jxLh/WF1huv8WI/G2nthBCTAxv11ECLDRHuW5UnGaRA=; b=sVPOAZb7ndrnRKibQBkXqQwpFmdA3PfeFbCzAXAPVzR+A9gcEUGKJaHxwtYke0+i5i t8VHgjiLLUBKZTKpmBX3v+qoLFrt+7zHVYyTRlmtGCV6iak/m+M5cqpIuEHJ4e6vVkp0 8z1oK4c5qyk7+dlaKXEvpgWQWkpnsNgx2ZbyRAMyZA8vWMGQkQ1+1H0gL9FBKCczheDo dRCaxZnVJJVLthNliznfqv04l5Z+V+b11FUhM5iKYevmYqw5AZcsvHla05OOZwDgeTaL Bc9YKWTCDea0C94FCTK4HdbIX3a1KALgst3PqyPeqnI1d/8ucmy6BbpIGvr8Kds/OAMI vIqQ== X-Gm-Message-State: AOAM533fzZVt3B7Ny8BvuApWIirsw06DvMlxpT0D0as88H9zgt5Jr4sK 4eZE9w+ZEAJiAJI4EPElToEkWsYxveg= X-Google-Smtp-Source: ABdhPJwlIykHa3//My9eAw7WPnqktxWupGNvlJtxZV0yproPCbTJ/tC04yGAT+0mAOeXkc0or5Q36g== X-Received: by 2002:a05:6402:157:: with SMTP id s23mr638494edu.282.1623346508617; Thu, 10 Jun 2021 10:35:08 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id g17sm1789595edp.14.2021.06.10.10.35.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 10:35:07 -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 net-next 09/10] net: dsa: sja1105: add the RX timestamping procedure for SJA1110 Date: Thu, 10 Jun 2021 20:34:24 +0300 Message-Id: <20210610173425.1791379-10-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610173425.1791379-1-olteanv@gmail.com> References: <20210610173425.1791379-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 --- 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 a6d64b27e6a9..201bca282884 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -130,6 +130,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); const char *name; bool supports_mii[SJA1105_MAX_NUM_PORTS]; 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 9156f4cc11f2..f7dd86271891 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -580,6 +580,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 = { @@ -612,6 +613,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 = { @@ -645,6 +647,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 = { @@ -678,6 +681,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 = { @@ -711,6 +715,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, .regs = &sja1105pqrs_regs, .port_speed = { @@ -746,6 +751,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, .port_speed = { [SJA1105_SPEED_AUTO] = 0, @@ -781,6 +787,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, .port_speed = { [SJA1105_SPEED_AUTO] = 0, @@ -828,6 +835,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, .port_speed = { [SJA1105_SPEED_AUTO] = 0, @@ -875,6 +883,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, .port_speed = { [SJA1105_SPEED_AUTO] = 0, @@ -922,6 +931,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, .port_speed = { [SJA1105_SPEED_AUTO] = 0, From patchwork Thu Jun 10 17:34: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: 458317 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 A45A2C47094 for ; Thu, 10 Jun 2021 17:35:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 812D9613E1 for ; Thu, 10 Jun 2021 17:35:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231178AbhFJRh2 (ORCPT ); Thu, 10 Jun 2021 13:37:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231124AbhFJRhW (ORCPT ); Thu, 10 Jun 2021 13:37:22 -0400 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C6EBC0617A8 for ; Thu, 10 Jun 2021 10:35:12 -0700 (PDT) Received: by mail-ed1-x52c.google.com with SMTP id i13so34011859edb.9 for ; Thu, 10 Jun 2021 10:35:12 -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=CY20aR77Xp9kZ48oWEPpIMd4qGPA/k6lpuOYJU7wiXk=; b=GR4Yvedtmfb+jw4y3zLdvq1TP37ttiYg5x7hZjIfl0brDwXPj7x/e8X/7TfigfCQFZ virk/Mth6IOPxJrJdQEYsdBcyK05+k4pCFVdU4GE30EL2QNXuPyUVMNRSRtXNy3LJ6Xo 4XZFn+bOtgR3P0OvhFWI1NnnupflR5v3tCQWvuBTMlvQiU9VbklnVClf2yd+DXdpk3Zh mCaMg8FDkbpwqDx+V2/bXjgqE+sy8A4j8V+mlMtCIDlZuvlV0A0upWsfbZ+Z9OCu/uvp VZMB7zQ8oYR9sgqSIQi6U7Qes1RUrRXnHSt6GPL3PICDHvqHH1IsyiGs+HQCBH/QGzbA NWzQ== 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=CY20aR77Xp9kZ48oWEPpIMd4qGPA/k6lpuOYJU7wiXk=; b=oIq9p0g1t8jRXfIWybSjtJbdV0ZwrUTWnLjoGBB0txisoWGC03CoX/jCdGSccmNGn/ PpbBUPfUEYI6ED5GXl8syHV6ZTqfB3qHuFMlDPA9pcSLldQc+Sy6R52csoStu+1U1zMy cfUkys14DG4KDHTeRc+PxyTtTxzM/tYwjI4PGwiaobv6bADgYYscfwNfMPALUnv0iytU zFG8oobsf8jX+FJMJKW5jc+8M3w2SHzrePUHqaXS3JbU/IlW4G5C/FNA/Vk6esu2xQ8/ b+c932+rHt2d3xMUvZSqQTDS3ltNx8ClFj0kM5Nrknxcpm7rXQOKGrf0knaPfe1H8Aou BmQw== X-Gm-Message-State: AOAM532lmpX28jiTo85sdVWpZ0AkB2jjn8wQMpc5+4xgg9cKXxejGPre bBpWqj3kakDe207hsNuhpv0= X-Google-Smtp-Source: ABdhPJyGttoiihogAO0MClGfVzDRU5Yoj6/iZEKdJ4IuY7XPAL5yNvd0B/njZAUlOkzJHuPnuQrKYQ== X-Received: by 2002:a05:6402:2790:: with SMTP id b16mr601080ede.115.1623346510772; Thu, 10 Jun 2021 10:35:10 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id g17sm1789595edp.14.2021.06.10.10.35.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Jun 2021 10:35:09 -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 net-next 10/10] net: dsa: sja1105: implement TX timestamping for SJA1110 Date: Thu, 10 Jun 2021 20:34:25 +0300 Message-Id: <20210610173425.1791379-11-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210610173425.1791379-1-olteanv@gmail.com> References: <20210610173425.1791379-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 --- drivers/net/dsa/sja1105/sja1105.h | 1 + drivers/net/dsa/sja1105/sja1105_ptp.c | 68 +++++++++++++++++++++++++++ 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, 155 insertions(+) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 201bca282884..5f3449351668 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -131,6 +131,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); const char *name; bool supports_mii[SJA1105_MAX_NUM_PORTS]; diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c index 62fe05b4cb60..72eb2cb5140b 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,66 @@ 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); +} + +/* 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 +530,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 +949,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 +977,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 f7dd86271891..32d00212423c 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -788,6 +788,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, .port_speed = { [SJA1105_SPEED_AUTO] = 0, @@ -836,6 +837,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, .port_speed = { [SJA1105_SPEED_AUTO] = 0, @@ -884,6 +886,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, .port_speed = { [SJA1105_SPEED_AUTO] = 0, @@ -932,6 +935,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, .port_speed = { [SJA1105_SPEED_AUTO] = 0, 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);