From patchwork Wed Apr 29 20:02:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Berger X-Patchwork-Id: 1279627 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=E8ctWVjq; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49C8ZB00Q0z9sSg for ; Thu, 30 Apr 2020 06:02:41 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727057AbgD2UCN (ORCPT ); Wed, 29 Apr 2020 16:02:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726456AbgD2UCM (ORCPT ); Wed, 29 Apr 2020 16:02:12 -0400 Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 40824C03C1AE; Wed, 29 Apr 2020 13:02:12 -0700 (PDT) Received: by mail-pf1-x444.google.com with SMTP id 18so1591064pfv.8; Wed, 29 Apr 2020 13:02: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; bh=CevivX0aGr8AmmZvoR5A9jtsq4aH4kUQzZm/M7FIZ5A=; b=E8ctWVjqQpu2nsC3Ydpfc3LtOwRwSwTFLxeQmSyOW7GOyuklsAGKUhnLYZB9c8CsNm hpp7dzl3Fd2wqkw4EbMylSk2epGKfN0TPB6mt4zjfeVkYTipehLvMlvMuZaO0CTUQ7gD oU8uDZvz0tBNyGI43+GQ8eoilcf7uESduagq48P5M1vNTAGiTY4pwN4luQt20aQ7OoNw qu6WQS4rhVoIS2pcvn3VaNL20p976+o1C0iflB/oSe9voUEerFo/AThNy0wmmkGCcsMY y4A+/YAY2Qb1ua47Z4KnX4bXjKKaVJyibTfqIkW7k8J8N0wq/L/a4is93rRPGTOqwssF aa1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CevivX0aGr8AmmZvoR5A9jtsq4aH4kUQzZm/M7FIZ5A=; b=pkz+u7qoMo4R7jonG3fkSC71MOGykA/Syo+D1jkA4btPbDZerT+JPRwsMtI7kWmAc7 WjOgJzfcbhxywISzyv70oQ4ztyoXB2chLgcDoTuhB/HH8u+qnaIAvqACVeOy+wuV4aVG imfb9PiirlSylcD+ICl4W7/tN+qNgL1cXQYvSHlHg8xdwfjEHwfjbVOVnPB0w6NYTfqd TD/pAoxnMiYbmCj3LCz9Ux4nzDIMFmxCuhvxa6eDXy600PHUKN/mucubVUrcxoHcd38P oJLkgNj1FtGXfZBfDuZgSh8JVV1/w4efigU7/02xPKTiTJIgzt54efDCEUaqZTLnKPw2 X/9g== X-Gm-Message-State: AGi0Puah/2YyI7/A8y0dwreTuAvCTSXDr/VDbgisw9RZqU8GjJ4/bLMJ cP2G4GwjJfCa/gJNuUegzHg= X-Google-Smtp-Source: APiQypImKV5ErRzSjavCApt6/HJl9CJMMMT7fj0bHkjKg0gkYmap9I/6LTUHWG0dNp63KbAHLkBTpw== X-Received: by 2002:a63:8c17:: with SMTP id m23mr17899491pgd.246.1588190531743; Wed, 29 Apr 2020 13:02:11 -0700 (PDT) Received: from stbirv-lnx-3.igp.broadcom.net ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id r128sm1705817pfc.141.2020.04.29.13.02.10 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Apr 2020 13:02:11 -0700 (PDT) From: Doug Berger To: Florian Fainelli , "David S. Miller" Cc: bcm-kernel-feedback-list@broadcom.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Doug Berger Subject: [PATCH net-next v2 1/7] net: bcmgenet: set Rx mode before starting netif Date: Wed, 29 Apr 2020 13:02:00 -0700 Message-Id: <1588190526-2082-2-git-send-email-opendmb@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1588190526-2082-1-git-send-email-opendmb@gmail.com> References: <1588190526-2082-1-git-send-email-opendmb@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This commit explicitly calls the bcmgenet_set_rx_mode() function when the network interface is started. This function is normally called by ndo_set_rx_mode when the flags are changed, but apparently not when the driver is suspended and resumed. This change ensures that address filtering or promiscuous mode are properly restored by the driver after the MAC may have been reset. Fixes: b6e978e50444 ("net: bcmgenet: add suspend/resume callbacks") Signed-off-by: Doug Berger Acked-by: Florian Fainelli --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 351d0282f199..eb0dd4d4800c 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -65,6 +65,9 @@ #define GENET_RDMA_REG_OFF (priv->hw_params->rdma_offset + \ TOTAL_DESC * DMA_DESC_SIZE) +/* Forward declarations */ +static void bcmgenet_set_rx_mode(struct net_device *dev); + static inline void bcmgenet_writel(u32 value, void __iomem *offset) { /* MIPS chips strapped for BE will automagically configure the @@ -2793,6 +2796,7 @@ static void bcmgenet_netif_start(struct net_device *dev) struct bcmgenet_priv *priv = netdev_priv(dev); /* Start the network engine */ + bcmgenet_set_rx_mode(dev); bcmgenet_enable_rx_napi(priv); umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true); From patchwork Wed Apr 29 20:02:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Berger X-Patchwork-Id: 1279628 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=kASBbSG2; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49C8ZF60jSz9sSM for ; Thu, 30 Apr 2020 06:02:45 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727850AbgD2UCm (ORCPT ); Wed, 29 Apr 2020 16:02:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727049AbgD2UCN (ORCPT ); Wed, 29 Apr 2020 16:02:13 -0400 Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7307EC03C1AE; Wed, 29 Apr 2020 13:02:13 -0700 (PDT) Received: by mail-pf1-x444.google.com with SMTP id f7so1587277pfa.9; Wed, 29 Apr 2020 13:02:13 -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; bh=SYWum3ZnYsfLSG0jDSyn5h0VUobSFoO/qhOlaCswZZY=; b=kASBbSG2Y+m0qJObDTSTlmTSkZyk0AhBnwpoKMvM1AO3HtMws3K+EBeAANoqC+Wr95 eRvbfwJTjDHFsPEfvVx2ZTJgEufX7iSaO+48GOeAl1+fPTvxBVUKXDKdoFkrxuXWl9mC XZHivxeGvDC2slGQGIQKk9b6oSDwm/NqanBRq42bKf1fJ3YTl734Ldu/4nmLQxnAjvC6 Lgif7O9E8JKZpEOZ9ESqtCP2cJ4d4DN/jj9OcWQ73qsP12y5kl2FcMoJrto5N8xf3Yam lwa5jxeLYaeG7KTvNfarmtUfbfTsrLsCKnxg1mToMWmSC8u3Y6XEgmIDvK2WI/5GTiNo 2/ag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SYWum3ZnYsfLSG0jDSyn5h0VUobSFoO/qhOlaCswZZY=; b=j+wAgXPX27Yn9kkWIPRLg564X0WNrSNnexFir10G1YYiThSMeGOMQ4Tx44z1+QMuHq msUmYCUPJhVllAEHuMOLXZoxF9wGTmT+XNkKJER8lcu3KkJHHdQ7pYU5SneWV4Nd7bYb uP2HhTe1C2f7NKgOfUDLPXGCLaG/ECOOjSCuUxzLoxJ3tOJz0C1/xu49lZ5Ga50CJU7R mntmZulD+u8MYqCuUGA8WrnioY603H8Q5bA7Qe7Ko42wjLaPGQco972cj34nXaSEPx2q vSuu08MhWwGkQx2A2kjp0uV0z8diFni2MkdnMaayj1gVIfldnDviQS2D9qjHwKB1s3oK xbSw== X-Gm-Message-State: AGi0PuZlKgmsZZZ13vvdQgtZ3DppT7apNV4acZRGOLqffRLUS3PA8Wmu kOojAxt8kleK/INxJrm+ThY= X-Google-Smtp-Source: APiQypJP3S9G2ZKqVVgcQlJkrH+KBcIg8Ek96iKCoB8qUyX9E4lyvZnHqhtRiIzaIPRdDm0v5H1+bQ== X-Received: by 2002:a63:1e5a:: with SMTP id p26mr34551434pgm.233.1588190532963; Wed, 29 Apr 2020 13:02:12 -0700 (PDT) Received: from stbirv-lnx-3.igp.broadcom.net ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id r128sm1705817pfc.141.2020.04.29.13.02.11 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Apr 2020 13:02:12 -0700 (PDT) From: Doug Berger To: Florian Fainelli , "David S. Miller" Cc: bcm-kernel-feedback-list@broadcom.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Doug Berger Subject: [PATCH net-next v2 2/7] net: bcmgenet: Fix WoL with password after deep sleep Date: Wed, 29 Apr 2020 13:02:01 -0700 Message-Id: <1588190526-2082-3-git-send-email-opendmb@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1588190526-2082-1-git-send-email-opendmb@gmail.com> References: <1588190526-2082-1-git-send-email-opendmb@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Broadcom STB chips support a deep sleep mode where all register contents are lost. Because we were stashing the MagicPacket password into some of these registers a suspend into that deep sleep then a resumption would not lead to being able to wake-up from MagicPacket with password again. Fix this by keeping a software copy of the password and program it during suspend. Fixes: c51de7f3976b ("net: bcmgenet: add Wake-on-LAN support code") Suggested-by: Florian Fainelli Signed-off-by: Doug Berger Acked-by: Florian Fainelli --- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 ++ drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 39 ++++++++++------------ 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index daf8fb2c39b6..c3bfe97f2e5c 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -14,6 +14,7 @@ #include #include #include +#include /* total number of Buffer Descriptors, same for Rx/Tx */ #define TOTAL_DESC 256 @@ -676,6 +677,7 @@ struct bcmgenet_priv { /* WOL */ struct clk *clk_wol; u32 wolopts; + u8 sopass[SOPASS_MAX]; struct bcmgenet_mib_counters mib; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c index c9a43695b182..597c0498689a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c @@ -41,18 +41,13 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct bcmgenet_priv *priv = netdev_priv(dev); - u32 reg; wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE; wol->wolopts = priv->wolopts; memset(wol->sopass, 0, sizeof(wol->sopass)); - if (wol->wolopts & WAKE_MAGICSECURE) { - reg = bcmgenet_umac_readl(priv, UMAC_MPD_PW_MS); - put_unaligned_be16(reg, &wol->sopass[0]); - reg = bcmgenet_umac_readl(priv, UMAC_MPD_PW_LS); - put_unaligned_be32(reg, &wol->sopass[2]); - } + if (wol->wolopts & WAKE_MAGICSECURE) + memcpy(wol->sopass, priv->sopass, sizeof(priv->sopass)); } /* ethtool function - set WOL (Wake on LAN) settings. @@ -62,7 +57,6 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct bcmgenet_priv *priv = netdev_priv(dev); struct device *kdev = &priv->pdev->dev; - u32 reg; if (!device_can_wakeup(kdev)) return -ENOTSUPP; @@ -70,17 +64,8 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE)) return -EINVAL; - reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); - if (wol->wolopts & WAKE_MAGICSECURE) { - bcmgenet_umac_writel(priv, get_unaligned_be16(&wol->sopass[0]), - UMAC_MPD_PW_MS); - bcmgenet_umac_writel(priv, get_unaligned_be32(&wol->sopass[2]), - UMAC_MPD_PW_LS); - reg |= MPD_PW_EN; - } else { - reg &= ~MPD_PW_EN; - } - bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); + if (wol->wolopts & WAKE_MAGICSECURE) + memcpy(priv->sopass, wol->sopass, sizeof(priv->sopass)); /* Flag the device and relevant IRQ as wakeup capable */ if (wol->wolopts) { @@ -120,6 +105,14 @@ static int bcmgenet_poll_wol_status(struct bcmgenet_priv *priv) return retries; } +static void bcmgenet_set_mpd_password(struct bcmgenet_priv *priv) +{ + bcmgenet_umac_writel(priv, get_unaligned_be16(&priv->sopass[0]), + UMAC_MPD_PW_MS); + bcmgenet_umac_writel(priv, get_unaligned_be32(&priv->sopass[2]), + UMAC_MPD_PW_LS); +} + int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, enum bcmgenet_power_mode mode) { @@ -144,13 +137,17 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); reg |= MPD_EN; + if (priv->wolopts & WAKE_MAGICSECURE) { + bcmgenet_set_mpd_password(priv); + reg |= MPD_PW_EN; + } bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); /* Do not leave UniMAC in MPD mode only */ retries = bcmgenet_poll_wol_status(priv); if (retries < 0) { reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); - reg &= ~MPD_EN; + reg &= ~(MPD_EN | MPD_PW_EN); bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); return retries; } @@ -189,7 +186,7 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv, reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); if (!(reg & MPD_EN)) return; /* already powered up so skip the rest */ - reg &= ~MPD_EN; + reg &= ~(MPD_EN | MPD_PW_EN); bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); /* Disable CRC Forward */ From patchwork Wed Apr 29 20:02:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Berger X-Patchwork-Id: 1279625 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=QrVTtIB0; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49C8Z23WC6z9sSM for ; Thu, 30 Apr 2020 06:02:34 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727096AbgD2UCR (ORCPT ); Wed, 29 Apr 2020 16:02:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57318 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726456AbgD2UCP (ORCPT ); Wed, 29 Apr 2020 16:02:15 -0400 Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1112DC03C1AE; Wed, 29 Apr 2020 13:02:15 -0700 (PDT) Received: by mail-pf1-x444.google.com with SMTP id 18so1594435pfx.6; Wed, 29 Apr 2020 13:02:15 -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; bh=ds8ghz/z0oHHp2naelmxlGEWoTQQpYGk6dQJe+ea0fA=; b=QrVTtIB0RMBXghkcxhf2NUQxtXuA2IlehvbTSV5bqnVj2k5m0koKMcPxTf0QRvd7xn NhczMSqBEGM/T4dDXC4Uu8Kkb8KEByLnevgE71f4t7ynH1rvbiNiCKpwDq/btlH2/SRu lMDfppMSZhKZpQlwYiQ4jwDWOK2f1vB2tOWBDQt9OM4nqzWB/D9v5Pwdr92JG+bIQftG nZ6vE70KjtC5dEpyqy+2MIHc8gkURdR+WNifVoqAvG4BXVstedJ84U3BFv1P412k0pMK Wt3L8JlpCwWSA7KQZEj6uZOqafkGHWAE6qxdB9OThgMMnyE67GRzOoUnaFEhTL1H+Uy5 Atng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ds8ghz/z0oHHp2naelmxlGEWoTQQpYGk6dQJe+ea0fA=; b=C/AAOkcLLpimTi13KV/yUpJ9P0hF69euu7tDAc3j5GTObEzyvMAlblYK0ZbBWuAVq7 uSKVS3LF+X9jmz/mpTeCNndoiABb2JIWxAoOq1MfE9t/KvLzsIIj2OSyErwcuKD2zwcY mtpQ2/i/ub4hE8kkw9nXU+ynlc2HDTWuqaMBCQcM/KkTw7Dhoge+RwCQ0cVoNhHW18Q/ xVk6PVTyle+flAYzSnS0j1vUqo8Zh79PfdHr4hx1ynTZPUSlX/JGg+7iFrUXii2ZoaXc A15FMWc4yfO7HM6SXKiXKSaGM2lkkxcuVLLWkvvOMLuwk0ENS1o+/biP6R51ydwTFC6b 8Eyg== X-Gm-Message-State: AGi0PuaGeZ+fx8SP79ArcSwL9LSg2i5SVPTOwq/T2tuSBvwUeY/hgPyF velpPomLXI3c5crtI+kCCq8= X-Google-Smtp-Source: APiQypKsZoHihciLLuJ5eJ19zmznYjgo/XaVwlsSS1iPdHt4AA/HtkQW1aYGOP635/iIw53j6R8o5Q== X-Received: by 2002:a62:64cd:: with SMTP id y196mr33130930pfb.116.1588190534587; Wed, 29 Apr 2020 13:02:14 -0700 (PDT) Received: from stbirv-lnx-3.igp.broadcom.net ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id r128sm1705817pfc.141.2020.04.29.13.02.13 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Apr 2020 13:02:13 -0700 (PDT) From: Doug Berger To: Florian Fainelli , "David S. Miller" Cc: bcm-kernel-feedback-list@broadcom.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Doug Berger Subject: [PATCH net-next v2 3/7] net: bcmgenet: move clk_wol management to bcmgenet_wol Date: Wed, 29 Apr 2020 13:02:02 -0700 Message-Id: <1588190526-2082-4-git-send-email-opendmb@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1588190526-2082-1-git-send-email-opendmb@gmail.com> References: <1588190526-2082-1-git-send-email-opendmb@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The GENET_POWER_WOL_MAGIC power up and power down code configures the device for WoL when suspending and disables the WoL logic when resuming. It makes sense that this code should also manage the WoL clocking. This commit consolidates the logic and moves it earlier in the resume sequence. Since the clock is now only enabled if WoL is successfully entered the wol_active flag is introduced to track that state to keep the clock enables and disables balanced in case a suspend is aborted. The MPD_EN hardware bit can't be used because it can be cleared when the MAC is reset by a deep sleep. Signed-off-by: Doug Berger Acked-by: Florian Fainelli --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 19 +++++++------------ drivers/net/ethernet/broadcom/genet/bcmgenet.h | 3 ++- drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 14 +++++++++++--- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index eb0dd4d4800c..57b8608feae1 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2,7 +2,7 @@ /* * Broadcom GENET (Gigabit Ethernet) controller driver * - * Copyright (c) 2014-2019 Broadcom + * Copyright (c) 2014-2020 Broadcom */ #define pr_fmt(fmt) "bcmgenet: " fmt @@ -3619,6 +3619,10 @@ static int bcmgenet_resume(struct device *d) if (ret) return ret; + /* From WOL-enabled suspend, switch to regular clock */ + if (device_may_wakeup(d) && priv->wolopts) + bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC); + /* If this is an internal GPHY, power it back on now, before UniMAC is * brought out of reset as absolutely no UniMAC activity is allowed */ @@ -3629,10 +3633,6 @@ static int bcmgenet_resume(struct device *d) init_umac(priv); - /* From WOL-enabled suspend, switch to regular clock */ - if (priv->wolopts) - clk_disable_unprepare(priv->clk_wol); - phy_init_hw(dev->phydev); /* Speed settings must be restored */ @@ -3650,9 +3650,6 @@ static int bcmgenet_resume(struct device *d) bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); } - if (priv->wolopts) - bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC); - /* Disable RX/TX DMA and flush TX queues */ dma_ctrl = bcmgenet_dma_disable(priv); @@ -3702,12 +3699,10 @@ static int bcmgenet_suspend(struct device *d) phy_suspend(dev->phydev); /* Prepare the device for Wake-on-LAN and switch to the slow clock */ - if (device_may_wakeup(d) && priv->wolopts) { + if (device_may_wakeup(d) && priv->wolopts) ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); - clk_prepare_enable(priv->clk_wol); - } else if (priv->internal_phy) { + else if (priv->internal_phy) ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE); - } /* Turn off the clocks */ clk_disable_unprepare(priv->clk); diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index c3bfe97f2e5c..a858b7305832 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2014-2017 Broadcom + * Copyright (c) 2014-2020 Broadcom */ #ifndef __BCMGENET_H__ @@ -678,6 +678,7 @@ struct bcmgenet_priv { struct clk *clk_wol; u32 wolopts; u8 sopass[SOPASS_MAX]; + bool wol_active; struct bcmgenet_mib_counters mib; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c index 597c0498689a..da45a4645b94 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c @@ -2,7 +2,7 @@ /* * Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support * - * Copyright (c) 2014-2017 Broadcom + * Copyright (c) 2014-2020 Broadcom */ #define pr_fmt(fmt) "bcmgenet_wol: " fmt @@ -155,6 +155,9 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, netif_dbg(priv, wol, dev, "MPD WOL-ready status set after %d msec\n", retries); + clk_prepare_enable(priv->clk_wol); + priv->wol_active = 1; + /* Enable CRC forward */ reg = bcmgenet_umac_readl(priv, UMAC_CMD); priv->crc_fwd_en = 1; @@ -183,9 +186,14 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv, return; } + if (!priv->wol_active) + return; /* failed to suspend so skip the rest */ + + priv->wol_active = 0; + clk_disable_unprepare(priv->clk_wol); + + /* Disable Magic Packet Detection */ reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); - if (!(reg & MPD_EN)) - return; /* already powered up so skip the rest */ reg &= ~(MPD_EN | MPD_PW_EN); bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); From patchwork Wed Apr 29 20:02:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Berger X-Patchwork-Id: 1279626 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Q3tvhdUR; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49C8Z466qFz9sSM for ; Thu, 30 Apr 2020 06:02:36 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727827AbgD2UCg (ORCPT ); Wed, 29 Apr 2020 16:02:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57320 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727079AbgD2UCQ (ORCPT ); Wed, 29 Apr 2020 16:02:16 -0400 Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 56210C03C1AE; Wed, 29 Apr 2020 13:02:16 -0700 (PDT) Received: by mail-pg1-x542.google.com with SMTP id o185so1535460pgo.3; Wed, 29 Apr 2020 13:02:16 -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; bh=IC8rInsRsfxQQkeZ96jiqZI2NB9+ZDmlgZxQ89+Ot80=; b=Q3tvhdURxNnI8eipt1UAAyDjRNDvN3MOcBNT/modDn4FhNs/nXY29BN63vDWNfwymx yOfBHJDQPmQT47fEVquMDbtT5pqnXVCS5QJ/AZ/mrL6/DaZprbDCt0/VU0kBqh4zniVV XNEnZXluePl5kVGSGOGttZ+Jqct5kpfKSZigh++PvWGJQTHdyDdLLulMiACzcAHHZs1Q B4c4w6Iwk6xFGPx1pFDo3hIxNzBw7SMlTIpPh0lRQ20O6f3PKTfOk3nnROlRBrehUtdm hew0i+G/hAp+KTKjyrbcaKhS9w0o57Ki0YnCl4fc9WVlVVPcBp/5fIlcPD8lgusynfYm uJ/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=IC8rInsRsfxQQkeZ96jiqZI2NB9+ZDmlgZxQ89+Ot80=; b=iJNBYsCIiDkMzpbnPpPKq6ceLnYkYBErAmwaVw5dsxp/ncil2VGTVM0AhwV8Yjns/U a5kHM3IbGYWMtac+sVoveCynsPrd1s3g+LKWZKIwn6AUyyvQRXj5+xPKKep4oTV/cNHq fD0qjj2S/IMhADNOIEXP7TW/4j+HdOZzb+bwfxivSDnsxghrZmRi/bO3PbBz5SPaMjlx ebCiNiPaCLGobzEhejoAGU2g/NWHc/4VM8Lko5qMsQp+6Ow5nahURpvLhnfKs7LbtVYI VvPjWieJ19xys2LLbIqGKf8GIjhlVrKNVEMm7202ssKg8R3sXY4dDfqnC1/M+5dN32a1 b7LQ== X-Gm-Message-State: AGi0PuYc9qraZULP+ElLXa9a60n08O1kXLYw7X+gpK+9Hh1j7S85T65b Iuam0um0d2eoX/hwCxPBDXE= X-Google-Smtp-Source: APiQypLcivI2c+n9PIkReQk7m+dnLg8JBlSifrz4L3rmjTEVTW+cwfWf5Q6OxQrSMZo+1M3YJdY7tQ== X-Received: by 2002:a63:5704:: with SMTP id l4mr9729669pgb.85.1588190535828; Wed, 29 Apr 2020 13:02:15 -0700 (PDT) Received: from stbirv-lnx-3.igp.broadcom.net ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id r128sm1705817pfc.141.2020.04.29.13.02.14 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Apr 2020 13:02:15 -0700 (PDT) From: Doug Berger To: Florian Fainelli , "David S. Miller" Cc: bcm-kernel-feedback-list@broadcom.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Doug Berger Subject: [PATCH net-next v2 4/7] Revert "net: bcmgenet: remove unused function in bcmgenet.c" Date: Wed, 29 Apr 2020 13:02:03 -0700 Message-Id: <1588190526-2082-5-git-send-email-opendmb@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1588190526-2082-1-git-send-email-opendmb@gmail.com> References: <1588190526-2082-1-git-send-email-opendmb@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This reverts commit e2072600a24161b7ddcfb26814f69f5fbc8ef85a. This commit restores the previous implementation of Hardware Filter Block functions to the file for use in subsequent commits. Signed-off-by: Doug Berger Acked-by: Florian Fainelli --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 122 +++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 57b8608feae1..b37ef05c5083 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2759,6 +2759,128 @@ static void bcmgenet_enable_dma(struct bcmgenet_priv *priv, u32 dma_ctrl) bcmgenet_tdma_writel(priv, reg, DMA_CTRL); } +static bool bcmgenet_hfb_is_filter_enabled(struct bcmgenet_priv *priv, + u32 f_index) +{ + u32 offset; + u32 reg; + + offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32); + reg = bcmgenet_hfb_reg_readl(priv, offset); + return !!(reg & (1 << (f_index % 32))); +} + +static void bcmgenet_hfb_enable_filter(struct bcmgenet_priv *priv, u32 f_index) +{ + u32 offset; + u32 reg; + + offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32); + reg = bcmgenet_hfb_reg_readl(priv, offset); + reg |= (1 << (f_index % 32)); + bcmgenet_hfb_reg_writel(priv, reg, offset); +} + +static void bcmgenet_hfb_set_filter_rx_queue_mapping(struct bcmgenet_priv *priv, + u32 f_index, u32 rx_queue) +{ + u32 offset; + u32 reg; + + offset = f_index / 8; + reg = bcmgenet_rdma_readl(priv, DMA_INDEX2RING_0 + offset); + reg &= ~(0xF << (4 * (f_index % 8))); + reg |= ((rx_queue & 0xF) << (4 * (f_index % 8))); + bcmgenet_rdma_writel(priv, reg, DMA_INDEX2RING_0 + offset); +} + +static void bcmgenet_hfb_set_filter_length(struct bcmgenet_priv *priv, + u32 f_index, u32 f_length) +{ + u32 offset; + u32 reg; + + offset = HFB_FLT_LEN_V3PLUS + + ((priv->hw_params->hfb_filter_cnt - 1 - f_index) / 4) * + sizeof(u32); + reg = bcmgenet_hfb_reg_readl(priv, offset); + reg &= ~(0xFF << (8 * (f_index % 4))); + reg |= ((f_length & 0xFF) << (8 * (f_index % 4))); + bcmgenet_hfb_reg_writel(priv, reg, offset); +} + +static int bcmgenet_hfb_find_unused_filter(struct bcmgenet_priv *priv) +{ + u32 f_index; + + for (f_index = 0; f_index < priv->hw_params->hfb_filter_cnt; f_index++) + if (!bcmgenet_hfb_is_filter_enabled(priv, f_index)) + return f_index; + + return -ENOMEM; +} + +/* bcmgenet_hfb_add_filter + * + * Add new filter to Hardware Filter Block to match and direct Rx traffic to + * desired Rx queue. + * + * f_data is an array of unsigned 32-bit integers where each 32-bit integer + * provides filter data for 2 bytes (4 nibbles) of Rx frame: + * + * bits 31:20 - unused + * bit 19 - nibble 0 match enable + * bit 18 - nibble 1 match enable + * bit 17 - nibble 2 match enable + * bit 16 - nibble 3 match enable + * bits 15:12 - nibble 0 data + * bits 11:8 - nibble 1 data + * bits 7:4 - nibble 2 data + * bits 3:0 - nibble 3 data + * + * Example: + * In order to match: + * - Ethernet frame type = 0x0800 (IP) + * - IP version field = 4 + * - IP protocol field = 0x11 (UDP) + * + * The following filter is needed: + * u32 hfb_filter_ipv4_udp[] = { + * Rx frame offset 0x00: 0x00000000, 0x00000000, 0x00000000, 0x00000000, + * Rx frame offset 0x08: 0x00000000, 0x00000000, 0x000F0800, 0x00084000, + * Rx frame offset 0x10: 0x00000000, 0x00000000, 0x00000000, 0x00030011, + * }; + * + * To add the filter to HFB and direct the traffic to Rx queue 0, call: + * bcmgenet_hfb_add_filter(priv, hfb_filter_ipv4_udp, + * ARRAY_SIZE(hfb_filter_ipv4_udp), 0); + */ +int bcmgenet_hfb_add_filter(struct bcmgenet_priv *priv, u32 *f_data, + u32 f_length, u32 rx_queue) +{ + int f_index; + u32 i; + + f_index = bcmgenet_hfb_find_unused_filter(priv); + if (f_index < 0) + return -ENOMEM; + + if (f_length > priv->hw_params->hfb_filter_size) + return -EINVAL; + + for (i = 0; i < f_length; i++) + bcmgenet_hfb_writel(priv, f_data[i], + (f_index * priv->hw_params->hfb_filter_size + i) * + sizeof(u32)); + + bcmgenet_hfb_set_filter_length(priv, f_index, 2 * f_length); + bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f_index, rx_queue); + bcmgenet_hfb_enable_filter(priv, f_index); + bcmgenet_hfb_reg_writel(priv, 0x1, HFB_CTRL); + + return 0; +} + /* bcmgenet_hfb_clear * * Clear Hardware Filter Block and disable all filtering. From patchwork Wed Apr 29 20:02:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Berger X-Patchwork-Id: 1279622 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=oirCxvG4; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49C8Yp1vj7z9sSh for ; Thu, 30 Apr 2020 06:02:22 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727114AbgD2UCT (ORCPT ); Wed, 29 Apr 2020 16:02:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726456AbgD2UCR (ORCPT ); Wed, 29 Apr 2020 16:02:17 -0400 Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70615C03C1AE; Wed, 29 Apr 2020 13:02:17 -0700 (PDT) Received: by mail-pg1-x544.google.com with SMTP id n11so1522427pgl.9; Wed, 29 Apr 2020 13:02:17 -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; bh=Lt2wsDTP1dZbAx86w3ZjTWR6LwcLzUhJBjuXStdHEjY=; b=oirCxvG4LhoXUizdVbVdUgL/5JkKqH+lNIaU5bS5rK9zyKlV20Dx4RnQygjhsd2uBj MWHccuOLUki4vjwX/sdq+dvXIQZI2JrpWZB0RXpoxkh86PWJL0BnKxDU7Xb5olA6S+Sg Bs42yz8EpB7pxwH1/jJTX0aw/I8+ZrQx6ZZfVS4NgnZcbIcdfEeNjjeT1I9ck6nVJHRD CXxdTUhZUCmMFFR46O+iCf6FJ5p1usEfT0bVrRIMXx3mEXjJ3LIYrvFBP2VlIh30y6oI bW2N8lvkdPBLbgKQ06hDjP9/XXbuXUxZJ8cyr9inpTv6laLw2oMpcDgcVTkkKnPV+tG0 AwAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Lt2wsDTP1dZbAx86w3ZjTWR6LwcLzUhJBjuXStdHEjY=; b=WSpf/47twqOR0UgHkEU+WyNm+i9DCoCnwNQ09nzC4p4qz3ZkV3P7sWGCBKDEHgh6Uq MR52Bh/yH0DerTRktnUTJutEc409KZEwdqJQYjAgspyMycY8L9HOb8UrcMawifsVKMYJ UOEsgyW8PYaoUsyAo5KqMQbxR9SqXdN4apCIdJQoYEO4kC9UgvppOPPOlY7Zn3OS7uMj JODcWvMK3WNaWPhczxShF5tRyxksD/9rU2pN8nVPn/T9nGd+/G5bzGWpxvZBSjAKdgo7 rKtLWwgNuyueoU3uOsYeCalsCXNcsOjq/Cu1j4vHnszhONL4Kqr9juab2PRozoLB2DA0 z14A== X-Gm-Message-State: AGi0PuabWCRvUM7FVKVpI2m+eBvy6XyfDn0GOwFWi9GrS17fnIWeuTK5 /VW+UnEr0225qwNZK3MtuI4= X-Google-Smtp-Source: APiQypJ5vwo8lRBHBtV2r+bMeb0emMNKMyR6/mF9LmYX2IHiq+4LjN5GMp6Vqa4V+pPx8we89GjhhA== X-Received: by 2002:a63:fa0e:: with SMTP id y14mr33417154pgh.13.1588190536858; Wed, 29 Apr 2020 13:02:16 -0700 (PDT) Received: from stbirv-lnx-3.igp.broadcom.net ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id r128sm1705817pfc.141.2020.04.29.13.02.16 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Apr 2020 13:02:16 -0700 (PDT) From: Doug Berger To: Florian Fainelli , "David S. Miller" Cc: bcm-kernel-feedback-list@broadcom.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Doug Berger Subject: [PATCH net-next v2 5/7] net: bcmgenet: code movement Date: Wed, 29 Apr 2020 13:02:04 -0700 Message-Id: <1588190526-2082-6-git-send-email-opendmb@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1588190526-2082-1-git-send-email-opendmb@gmail.com> References: <1588190526-2082-1-git-send-email-opendmb@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The Hardware Filter Block code will be used by ethtool functions when defining flow types so this commit moves the functions in the file to prevent the need for prototype declarations. This is broken out to facilitate review. Signed-off-by: Doug Berger Acked-by: Florian Fainelli --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 308 ++++++++++++------------- 1 file changed, 154 insertions(+), 154 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index b37ef05c5083..ad41944d2cc0 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -459,6 +459,160 @@ static inline void bcmgenet_rdma_ring_writel(struct bcmgenet_priv *priv, genet_dma_ring_regs[r]); } +static bool bcmgenet_hfb_is_filter_enabled(struct bcmgenet_priv *priv, + u32 f_index) +{ + u32 offset; + u32 reg; + + offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32); + reg = bcmgenet_hfb_reg_readl(priv, offset); + return !!(reg & (1 << (f_index % 32))); +} + +static void bcmgenet_hfb_enable_filter(struct bcmgenet_priv *priv, u32 f_index) +{ + u32 offset; + u32 reg; + + offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32); + reg = bcmgenet_hfb_reg_readl(priv, offset); + reg |= (1 << (f_index % 32)); + bcmgenet_hfb_reg_writel(priv, reg, offset); +} + +static void bcmgenet_hfb_set_filter_rx_queue_mapping(struct bcmgenet_priv *priv, + u32 f_index, u32 rx_queue) +{ + u32 offset; + u32 reg; + + offset = f_index / 8; + reg = bcmgenet_rdma_readl(priv, DMA_INDEX2RING_0 + offset); + reg &= ~(0xF << (4 * (f_index % 8))); + reg |= ((rx_queue & 0xF) << (4 * (f_index % 8))); + bcmgenet_rdma_writel(priv, reg, DMA_INDEX2RING_0 + offset); +} + +static void bcmgenet_hfb_set_filter_length(struct bcmgenet_priv *priv, + u32 f_index, u32 f_length) +{ + u32 offset; + u32 reg; + + offset = HFB_FLT_LEN_V3PLUS + + ((priv->hw_params->hfb_filter_cnt - 1 - f_index) / 4) * + sizeof(u32); + reg = bcmgenet_hfb_reg_readl(priv, offset); + reg &= ~(0xFF << (8 * (f_index % 4))); + reg |= ((f_length & 0xFF) << (8 * (f_index % 4))); + bcmgenet_hfb_reg_writel(priv, reg, offset); +} + +static int bcmgenet_hfb_find_unused_filter(struct bcmgenet_priv *priv) +{ + u32 f_index; + + for (f_index = 0; f_index < priv->hw_params->hfb_filter_cnt; f_index++) + if (!bcmgenet_hfb_is_filter_enabled(priv, f_index)) + return f_index; + + return -ENOMEM; +} + +/* bcmgenet_hfb_add_filter + * + * Add new filter to Hardware Filter Block to match and direct Rx traffic to + * desired Rx queue. + * + * f_data is an array of unsigned 32-bit integers where each 32-bit integer + * provides filter data for 2 bytes (4 nibbles) of Rx frame: + * + * bits 31:20 - unused + * bit 19 - nibble 0 match enable + * bit 18 - nibble 1 match enable + * bit 17 - nibble 2 match enable + * bit 16 - nibble 3 match enable + * bits 15:12 - nibble 0 data + * bits 11:8 - nibble 1 data + * bits 7:4 - nibble 2 data + * bits 3:0 - nibble 3 data + * + * Example: + * In order to match: + * - Ethernet frame type = 0x0800 (IP) + * - IP version field = 4 + * - IP protocol field = 0x11 (UDP) + * + * The following filter is needed: + * u32 hfb_filter_ipv4_udp[] = { + * Rx frame offset 0x00: 0x00000000, 0x00000000, 0x00000000, 0x00000000, + * Rx frame offset 0x08: 0x00000000, 0x00000000, 0x000F0800, 0x00084000, + * Rx frame offset 0x10: 0x00000000, 0x00000000, 0x00000000, 0x00030011, + * }; + * + * To add the filter to HFB and direct the traffic to Rx queue 0, call: + * bcmgenet_hfb_add_filter(priv, hfb_filter_ipv4_udp, + * ARRAY_SIZE(hfb_filter_ipv4_udp), 0); + */ +int bcmgenet_hfb_add_filter(struct bcmgenet_priv *priv, u32 *f_data, + u32 f_length, u32 rx_queue) +{ + int f_index; + u32 i; + + f_index = bcmgenet_hfb_find_unused_filter(priv); + if (f_index < 0) + return -ENOMEM; + + if (f_length > priv->hw_params->hfb_filter_size) + return -EINVAL; + + for (i = 0; i < f_length; i++) + bcmgenet_hfb_writel(priv, f_data[i], + (f_index * priv->hw_params->hfb_filter_size + i) * + sizeof(u32)); + + bcmgenet_hfb_set_filter_length(priv, f_index, 2 * f_length); + bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f_index, rx_queue); + bcmgenet_hfb_enable_filter(priv, f_index); + bcmgenet_hfb_reg_writel(priv, 0x1, HFB_CTRL); + + return 0; +} + +/* bcmgenet_hfb_clear + * + * Clear Hardware Filter Block and disable all filtering. + */ +static void bcmgenet_hfb_clear(struct bcmgenet_priv *priv) +{ + u32 i; + + bcmgenet_hfb_reg_writel(priv, 0x0, HFB_CTRL); + bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS); + bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS + 4); + + for (i = DMA_INDEX2RING_0; i <= DMA_INDEX2RING_7; i++) + bcmgenet_rdma_writel(priv, 0x0, i); + + for (i = 0; i < (priv->hw_params->hfb_filter_cnt / 4); i++) + bcmgenet_hfb_reg_writel(priv, 0x0, + HFB_FLT_LEN_V3PLUS + i * sizeof(u32)); + + for (i = 0; i < priv->hw_params->hfb_filter_cnt * + priv->hw_params->hfb_filter_size; i++) + bcmgenet_hfb_writel(priv, 0x0, i * sizeof(u32)); +} + +static void bcmgenet_hfb_init(struct bcmgenet_priv *priv) +{ + if (GENET_IS_V1(priv) || GENET_IS_V2(priv)) + return; + + bcmgenet_hfb_clear(priv); +} + static int bcmgenet_begin(struct net_device *dev) { struct bcmgenet_priv *priv = netdev_priv(dev); @@ -2759,160 +2913,6 @@ static void bcmgenet_enable_dma(struct bcmgenet_priv *priv, u32 dma_ctrl) bcmgenet_tdma_writel(priv, reg, DMA_CTRL); } -static bool bcmgenet_hfb_is_filter_enabled(struct bcmgenet_priv *priv, - u32 f_index) -{ - u32 offset; - u32 reg; - - offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32); - reg = bcmgenet_hfb_reg_readl(priv, offset); - return !!(reg & (1 << (f_index % 32))); -} - -static void bcmgenet_hfb_enable_filter(struct bcmgenet_priv *priv, u32 f_index) -{ - u32 offset; - u32 reg; - - offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32); - reg = bcmgenet_hfb_reg_readl(priv, offset); - reg |= (1 << (f_index % 32)); - bcmgenet_hfb_reg_writel(priv, reg, offset); -} - -static void bcmgenet_hfb_set_filter_rx_queue_mapping(struct bcmgenet_priv *priv, - u32 f_index, u32 rx_queue) -{ - u32 offset; - u32 reg; - - offset = f_index / 8; - reg = bcmgenet_rdma_readl(priv, DMA_INDEX2RING_0 + offset); - reg &= ~(0xF << (4 * (f_index % 8))); - reg |= ((rx_queue & 0xF) << (4 * (f_index % 8))); - bcmgenet_rdma_writel(priv, reg, DMA_INDEX2RING_0 + offset); -} - -static void bcmgenet_hfb_set_filter_length(struct bcmgenet_priv *priv, - u32 f_index, u32 f_length) -{ - u32 offset; - u32 reg; - - offset = HFB_FLT_LEN_V3PLUS + - ((priv->hw_params->hfb_filter_cnt - 1 - f_index) / 4) * - sizeof(u32); - reg = bcmgenet_hfb_reg_readl(priv, offset); - reg &= ~(0xFF << (8 * (f_index % 4))); - reg |= ((f_length & 0xFF) << (8 * (f_index % 4))); - bcmgenet_hfb_reg_writel(priv, reg, offset); -} - -static int bcmgenet_hfb_find_unused_filter(struct bcmgenet_priv *priv) -{ - u32 f_index; - - for (f_index = 0; f_index < priv->hw_params->hfb_filter_cnt; f_index++) - if (!bcmgenet_hfb_is_filter_enabled(priv, f_index)) - return f_index; - - return -ENOMEM; -} - -/* bcmgenet_hfb_add_filter - * - * Add new filter to Hardware Filter Block to match and direct Rx traffic to - * desired Rx queue. - * - * f_data is an array of unsigned 32-bit integers where each 32-bit integer - * provides filter data for 2 bytes (4 nibbles) of Rx frame: - * - * bits 31:20 - unused - * bit 19 - nibble 0 match enable - * bit 18 - nibble 1 match enable - * bit 17 - nibble 2 match enable - * bit 16 - nibble 3 match enable - * bits 15:12 - nibble 0 data - * bits 11:8 - nibble 1 data - * bits 7:4 - nibble 2 data - * bits 3:0 - nibble 3 data - * - * Example: - * In order to match: - * - Ethernet frame type = 0x0800 (IP) - * - IP version field = 4 - * - IP protocol field = 0x11 (UDP) - * - * The following filter is needed: - * u32 hfb_filter_ipv4_udp[] = { - * Rx frame offset 0x00: 0x00000000, 0x00000000, 0x00000000, 0x00000000, - * Rx frame offset 0x08: 0x00000000, 0x00000000, 0x000F0800, 0x00084000, - * Rx frame offset 0x10: 0x00000000, 0x00000000, 0x00000000, 0x00030011, - * }; - * - * To add the filter to HFB and direct the traffic to Rx queue 0, call: - * bcmgenet_hfb_add_filter(priv, hfb_filter_ipv4_udp, - * ARRAY_SIZE(hfb_filter_ipv4_udp), 0); - */ -int bcmgenet_hfb_add_filter(struct bcmgenet_priv *priv, u32 *f_data, - u32 f_length, u32 rx_queue) -{ - int f_index; - u32 i; - - f_index = bcmgenet_hfb_find_unused_filter(priv); - if (f_index < 0) - return -ENOMEM; - - if (f_length > priv->hw_params->hfb_filter_size) - return -EINVAL; - - for (i = 0; i < f_length; i++) - bcmgenet_hfb_writel(priv, f_data[i], - (f_index * priv->hw_params->hfb_filter_size + i) * - sizeof(u32)); - - bcmgenet_hfb_set_filter_length(priv, f_index, 2 * f_length); - bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f_index, rx_queue); - bcmgenet_hfb_enable_filter(priv, f_index); - bcmgenet_hfb_reg_writel(priv, 0x1, HFB_CTRL); - - return 0; -} - -/* bcmgenet_hfb_clear - * - * Clear Hardware Filter Block and disable all filtering. - */ -static void bcmgenet_hfb_clear(struct bcmgenet_priv *priv) -{ - u32 i; - - bcmgenet_hfb_reg_writel(priv, 0x0, HFB_CTRL); - bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS); - bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS + 4); - - for (i = DMA_INDEX2RING_0; i <= DMA_INDEX2RING_7; i++) - bcmgenet_rdma_writel(priv, 0x0, i); - - for (i = 0; i < (priv->hw_params->hfb_filter_cnt / 4); i++) - bcmgenet_hfb_reg_writel(priv, 0x0, - HFB_FLT_LEN_V3PLUS + i * sizeof(u32)); - - for (i = 0; i < priv->hw_params->hfb_filter_cnt * - priv->hw_params->hfb_filter_size; i++) - bcmgenet_hfb_writel(priv, 0x0, i * sizeof(u32)); -} - -static void bcmgenet_hfb_init(struct bcmgenet_priv *priv) -{ - if (GENET_IS_V1(priv) || GENET_IS_V2(priv)) - return; - - bcmgenet_hfb_clear(priv); -} - static void bcmgenet_netif_start(struct net_device *dev) { struct bcmgenet_priv *priv = netdev_priv(dev); From patchwork Wed Apr 29 20:02:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Berger X-Patchwork-Id: 1279623 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=pZ82uXfg; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49C8Yt5rwTz9sSj for ; Thu, 30 Apr 2020 06:02:26 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727811AbgD2UCY (ORCPT ); Wed, 29 Apr 2020 16:02:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57334 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727112AbgD2UCT (ORCPT ); Wed, 29 Apr 2020 16:02:19 -0400 Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E075EC03C1AE; Wed, 29 Apr 2020 13:02:18 -0700 (PDT) Received: by mail-pg1-x542.google.com with SMTP id d17so1543708pgo.0; Wed, 29 Apr 2020 13:02:18 -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; bh=XjH6F4JHAAsbYpUGPSJyG+L4O1JRXxsxIBKmTIPDjzI=; b=pZ82uXfgZNgUJHjLCidQKrsZV6Ei8JTm5tC2Vg2KRe06zXyxzfpBzd2Yx/1ge+/qzb 3Q0SIbLcaVlEDszJkfSx1iOaa5bplD+g+86QOMX8fnbMswCzj6NBjQThnFe1DAuXKt9i 05WP8QaD93BNAtMLN526ciwaRPagINs/P6WmoVxIPTv4FfmVuQYdLP4Jr3bAdCQ726O9 oW08u0sFXIKKPOlFZdDmsAkGBllZ3MrCBJeAoLc3I7OweII2PCS2V5uUvoGQI9uXKdw8 aefRgNTBFKiF1Jv5Ls6o0yqP5ehUmpZ9P6mZV+RrnSeohQPwqa2CnkJYUKKbiv1HHBuw CwNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=XjH6F4JHAAsbYpUGPSJyG+L4O1JRXxsxIBKmTIPDjzI=; b=nPDIGS2w872lPbtb//bIAI6icB406vDNBSFykbYn/IkAd98BbsxGlzNREvnljBS6la H6ejTydp9ORd2Ix6m6FQqVNVzppU0YvnNoTkapLmn6olCxLCpavIa/iT+r9KXqWcL+nq gR2qJfxPpf0jXv9fCr/EZCe76V9+v+lgB8e5hHEae/5uUdVtyu8aFxgS7UJhR29kjqOh tNLNU+G2qXToAIoiB2uNHT+Vs43AMVCmHoZkfE8mrbCZlXW8AiY76ua1vUg3JhZch/5P yPSl7g4zoKT8Frtuai4/dJcPmH96awCeibTPIHIZ/uOe3Vx8hnNFADeh7Ij8d8rwn7rA FeOA== X-Gm-Message-State: AGi0PuYoiJGlSBRnzpC3LkXqBbGuuwVff1MPcfUOgjYhAT8m00X/dt5C M7eBC43s2/T7lMo1OuzRhlY= X-Google-Smtp-Source: APiQypI7+Zsrx+5H6xuobPG9uuLacU8qBLpa+z91DJCSVBAB0k1Y4T8ZUuQvbsFxglFihOgi94lmYg== X-Received: by 2002:a63:5009:: with SMTP id e9mr33082604pgb.381.1588190538162; Wed, 29 Apr 2020 13:02:18 -0700 (PDT) Received: from stbirv-lnx-3.igp.broadcom.net ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id r128sm1705817pfc.141.2020.04.29.13.02.16 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Apr 2020 13:02:17 -0700 (PDT) From: Doug Berger To: Florian Fainelli , "David S. Miller" Cc: bcm-kernel-feedback-list@broadcom.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Doug Berger Subject: [PATCH net-next v2 6/7] net: bcmgenet: add support for ethtool rxnfc flows Date: Wed, 29 Apr 2020 13:02:05 -0700 Message-Id: <1588190526-2082-7-git-send-email-opendmb@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1588190526-2082-1-git-send-email-opendmb@gmail.com> References: <1588190526-2082-1-git-send-email-opendmb@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This commit enables driver support for ethtool commands of this form: ethtool -N|-U|--config-nfc|--config-ntuple devname flow-type ether|ip4 [src xx:yy:zz:aa:bb:cc [m xx:yy:zz:aa:bb:cc]] [dst xx:yy:zz:aa:bb:cc [m xx:yy:zz:aa:bb:cc]] [proto N [m N]] [src-ip x.x.x.x [m x.x.x.x]] [dst-ip x.x.x.x [m x.x.x.x]] [tos N [m N]] [l4proto N [m N]] [src-port N [m N]] [dst-port N [m N]] [spi N [m N]] [l4data N [m N]] [vlan-etype N [m N]] [vlan N [m N]] [dst-mac xx:yy:zz:aa:bb:cc [m xx:yy:zz:aa:bb:cc]] [action 0] [loc N] | delete N Since there is only one Rx Ring in this implementation action 0 behaves no differently from not specifying a rule. The rules can be seen with ethtool commands of this form: ethtool -n|-u|--show-nfc|--show-ntuple devname [rule N] Signed-off-by: Doug Berger Acked-by: Florian Fainelli --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 483 ++++++++++++++++++++++++- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 16 + 2 files changed, 488 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index ad41944d2cc0..5ef1ea7e5312 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -479,6 +479,30 @@ static void bcmgenet_hfb_enable_filter(struct bcmgenet_priv *priv, u32 f_index) reg = bcmgenet_hfb_reg_readl(priv, offset); reg |= (1 << (f_index % 32)); bcmgenet_hfb_reg_writel(priv, reg, offset); + reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL); + reg |= RBUF_HFB_EN; + bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL); +} + +static void bcmgenet_hfb_disable_filter(struct bcmgenet_priv *priv, u32 f_index) +{ + u32 offset, reg, reg1; + + offset = HFB_FLT_ENABLE_V3PLUS; + reg = bcmgenet_hfb_reg_readl(priv, offset); + reg1 = bcmgenet_hfb_reg_readl(priv, offset + sizeof(u32)); + if (f_index < 32) { + reg1 &= ~(1 << (f_index % 32)); + bcmgenet_hfb_reg_writel(priv, reg1, offset + sizeof(u32)); + } else { + reg &= ~(1 << (f_index % 32)); + bcmgenet_hfb_reg_writel(priv, reg, offset); + } + if (!reg && !reg1) { + reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL); + reg &= ~RBUF_HFB_EN; + bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL); + } } static void bcmgenet_hfb_set_filter_rx_queue_mapping(struct bcmgenet_priv *priv, @@ -513,13 +537,213 @@ static int bcmgenet_hfb_find_unused_filter(struct bcmgenet_priv *priv) { u32 f_index; - for (f_index = 0; f_index < priv->hw_params->hfb_filter_cnt; f_index++) + /* First MAX_NUM_OF_FS_RULES are reserved for Rx NFC filters */ + for (f_index = MAX_NUM_OF_FS_RULES; + f_index < priv->hw_params->hfb_filter_cnt; f_index++) if (!bcmgenet_hfb_is_filter_enabled(priv, f_index)) return f_index; return -ENOMEM; } +static int bcmgenet_hfb_validate_mask(void *mask, size_t size) +{ + while (size) { + switch (*(unsigned char *)mask++) { + case 0x00: + case 0x0f: + case 0xf0: + case 0xff: + size--; + continue; + default: + return -EINVAL; + } + } + + return 0; +} + +#define VALIDATE_MASK(x) \ + bcmgenet_hfb_validate_mask(&(x), sizeof(x)) + +static int bcmgenet_hfb_insert_data(u32 *f, int offset, + void *val, void *mask, size_t size) +{ + int index; + u32 tmp; + + index = offset / 2; + tmp = f[index]; + + while (size--) { + if (offset++ & 1) { + tmp &= ~0x300FF; + tmp |= (*(unsigned char *)val++); + switch ((*(unsigned char *)mask++)) { + case 0xFF: + tmp |= 0x30000; + break; + case 0xF0: + tmp |= 0x20000; + break; + case 0x0F: + tmp |= 0x10000; + break; + } + f[index++] = tmp; + if (size) + tmp = f[index]; + } else { + tmp &= ~0xCFF00; + tmp |= (*(unsigned char *)val++) << 8; + switch ((*(unsigned char *)mask++)) { + case 0xFF: + tmp |= 0xC0000; + break; + case 0xF0: + tmp |= 0x80000; + break; + case 0x0F: + tmp |= 0x40000; + break; + } + if (!size) + f[index] = tmp; + } + } + + return 0; +} + +static void bcmgenet_hfb_set_filter(struct bcmgenet_priv *priv, u32 *f_data, + u32 f_length, u32 rx_queue, int f_index) +{ + u32 base = f_index * priv->hw_params->hfb_filter_size; + int i; + + for (i = 0; i < f_length; i++) + bcmgenet_hfb_writel(priv, f_data[i], (base + i) * sizeof(u32)); + + bcmgenet_hfb_set_filter_length(priv, f_index, 2 * f_length); + bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f_index, rx_queue); +} + +static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, + struct bcmgenet_rxnfc_rule *rule) +{ + struct ethtool_rx_flow_spec *fs = &rule->fs; + int err = 0, offset = 0, f_length = 0; + u16 val_16, mask_16; + u8 val_8, mask_8; + size_t size; + u32 *f_data; + + f_data = kcalloc(priv->hw_params->hfb_filter_size, sizeof(u32), + GFP_KERNEL); + if (!f_data) + return -ENOMEM; + + if (fs->flow_type & FLOW_MAC_EXT) { + bcmgenet_hfb_insert_data(f_data, 0, + &fs->h_ext.h_dest, &fs->m_ext.h_dest, + sizeof(fs->h_ext.h_dest)); + } + + if (fs->flow_type & FLOW_EXT) { + if (fs->m_ext.vlan_etype || + fs->m_ext.vlan_tci) { + bcmgenet_hfb_insert_data(f_data, 12, + &fs->h_ext.vlan_etype, + &fs->m_ext.vlan_etype, + sizeof(fs->h_ext.vlan_etype)); + bcmgenet_hfb_insert_data(f_data, 14, + &fs->h_ext.vlan_tci, + &fs->m_ext.vlan_tci, + sizeof(fs->h_ext.vlan_tci)); + offset += VLAN_HLEN; + f_length += DIV_ROUND_UP(VLAN_HLEN, 2); + } + } + + switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { + case ETHER_FLOW: + f_length += DIV_ROUND_UP(ETH_HLEN, 2); + bcmgenet_hfb_insert_data(f_data, 0, + &fs->h_u.ether_spec.h_dest, + &fs->m_u.ether_spec.h_dest, + sizeof(fs->h_u.ether_spec.h_dest)); + bcmgenet_hfb_insert_data(f_data, ETH_ALEN, + &fs->h_u.ether_spec.h_source, + &fs->m_u.ether_spec.h_source, + sizeof(fs->h_u.ether_spec.h_source)); + bcmgenet_hfb_insert_data(f_data, (2 * ETH_ALEN) + offset, + &fs->h_u.ether_spec.h_proto, + &fs->m_u.ether_spec.h_proto, + sizeof(fs->h_u.ether_spec.h_proto)); + break; + case IP_USER_FLOW: + f_length += DIV_ROUND_UP(ETH_HLEN + 20, 2); + /* Specify IP Ether Type */ + val_16 = htons(ETH_P_IP); + mask_16 = 0xFFFF; + bcmgenet_hfb_insert_data(f_data, (2 * ETH_ALEN) + offset, + &val_16, &mask_16, sizeof(val_16)); + bcmgenet_hfb_insert_data(f_data, 15 + offset, + &fs->h_u.usr_ip4_spec.tos, + &fs->m_u.usr_ip4_spec.tos, + sizeof(fs->h_u.usr_ip4_spec.tos)); + bcmgenet_hfb_insert_data(f_data, 23 + offset, + &fs->h_u.usr_ip4_spec.proto, + &fs->m_u.usr_ip4_spec.proto, + sizeof(fs->h_u.usr_ip4_spec.proto)); + bcmgenet_hfb_insert_data(f_data, 26 + offset, + &fs->h_u.usr_ip4_spec.ip4src, + &fs->m_u.usr_ip4_spec.ip4src, + sizeof(fs->h_u.usr_ip4_spec.ip4src)); + bcmgenet_hfb_insert_data(f_data, 30 + offset, + &fs->h_u.usr_ip4_spec.ip4dst, + &fs->m_u.usr_ip4_spec.ip4dst, + sizeof(fs->h_u.usr_ip4_spec.ip4dst)); + if (!fs->m_u.usr_ip4_spec.l4_4_bytes) + break; + + /* Only supports 20 byte IPv4 header */ + val_8 = 0x45; + mask_8 = 0xFF; + bcmgenet_hfb_insert_data(f_data, ETH_HLEN + offset, + &val_8, &mask_8, + sizeof(val_8)); + size = sizeof(fs->h_u.usr_ip4_spec.l4_4_bytes); + bcmgenet_hfb_insert_data(f_data, + ETH_HLEN + 20 + offset, + &fs->h_u.usr_ip4_spec.l4_4_bytes, + &fs->m_u.usr_ip4_spec.l4_4_bytes, + size); + f_length += DIV_ROUND_UP(size, 2); + break; + } + + if (!fs->ring_cookie) { + /* Ring 0 flows can be handled by the default Descriptor Ring + * We'll map them to ring 0, but don't enable the filter + */ + bcmgenet_hfb_set_filter(priv, f_data, f_length, 0, + fs->location); + rule->state = BCMGENET_RXNFC_STATE_DISABLED; + } else { + /* Other Rx rings are direct mapped here */ + bcmgenet_hfb_set_filter(priv, f_data, f_length, + fs->ring_cookie, fs->location); + bcmgenet_hfb_enable_filter(priv, fs->location); + rule->state = BCMGENET_RXNFC_STATE_ENABLED; + } + + kfree(f_data); + + return err; +} + /* bcmgenet_hfb_add_filter * * Add new filter to Hardware Filter Block to match and direct Rx traffic to @@ -559,7 +783,6 @@ int bcmgenet_hfb_add_filter(struct bcmgenet_priv *priv, u32 *f_data, u32 f_length, u32 rx_queue) { int f_index; - u32 i; f_index = bcmgenet_hfb_find_unused_filter(priv); if (f_index < 0) @@ -568,15 +791,8 @@ int bcmgenet_hfb_add_filter(struct bcmgenet_priv *priv, u32 *f_data, if (f_length > priv->hw_params->hfb_filter_size) return -EINVAL; - for (i = 0; i < f_length; i++) - bcmgenet_hfb_writel(priv, f_data[i], - (f_index * priv->hw_params->hfb_filter_size + i) * - sizeof(u32)); - - bcmgenet_hfb_set_filter_length(priv, f_index, 2 * f_length); - bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f_index, rx_queue); + bcmgenet_hfb_set_filter(priv, f_data, f_length, rx_queue, f_index); bcmgenet_hfb_enable_filter(priv, f_index); - bcmgenet_hfb_reg_writel(priv, 0x1, HFB_CTRL); return 0; } @@ -607,9 +823,17 @@ static void bcmgenet_hfb_clear(struct bcmgenet_priv *priv) static void bcmgenet_hfb_init(struct bcmgenet_priv *priv) { + int i; + if (GENET_IS_V1(priv) || GENET_IS_V2(priv)) return; + INIT_LIST_HEAD(&priv->rxnfc_list); + for (i = 0; i < MAX_NUM_OF_FS_RULES; i++) { + INIT_LIST_HEAD(&priv->rxnfc_rules[i].list); + priv->rxnfc_rules[i].state = BCMGENET_RXNFC_STATE_UNUSED; + } + bcmgenet_hfb_clear(priv); } @@ -1197,6 +1421,228 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_eee *e) return phy_ethtool_set_eee(dev->phydev, e); } +static int bcmgenet_validate_flow(struct net_device *dev, + struct ethtool_rxnfc *cmd) +{ + struct ethtool_usrip4_spec *l4_mask; + struct ethhdr *eth_mask; + + if (cmd->fs.location >= MAX_NUM_OF_FS_RULES) { + netdev_err(dev, "rxnfc: Invalid location (%d)\n", + cmd->fs.location); + return -EINVAL; + } + + switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { + case IP_USER_FLOW: + l4_mask = &cmd->fs.m_u.usr_ip4_spec; + /* don't allow mask which isn't valid */ + if (VALIDATE_MASK(l4_mask->ip4src) || + VALIDATE_MASK(l4_mask->ip4dst) || + VALIDATE_MASK(l4_mask->l4_4_bytes) || + VALIDATE_MASK(l4_mask->proto) || + VALIDATE_MASK(l4_mask->ip_ver) || + VALIDATE_MASK(l4_mask->tos)) { + netdev_err(dev, "rxnfc: Unsupported mask\n"); + return -EINVAL; + } + break; + case ETHER_FLOW: + eth_mask = &cmd->fs.m_u.ether_spec; + /* don't allow mask which isn't valid */ + if (VALIDATE_MASK(eth_mask->h_source) || + VALIDATE_MASK(eth_mask->h_source) || + VALIDATE_MASK(eth_mask->h_proto)) { + netdev_err(dev, "rxnfc: Unsupported mask\n"); + return -EINVAL; + } + break; + default: + netdev_err(dev, "rxnfc: Unsupported flow type (0x%x)\n", + cmd->fs.flow_type); + return -EINVAL; + } + + if ((cmd->fs.flow_type & FLOW_EXT)) { + /* don't allow mask which isn't valid */ + if (VALIDATE_MASK(cmd->fs.m_ext.vlan_etype) || + VALIDATE_MASK(cmd->fs.m_ext.vlan_tci)) { + netdev_err(dev, "rxnfc: Unsupported mask\n"); + return -EINVAL; + } + if (cmd->fs.m_ext.data[0] || cmd->fs.m_ext.data[1]) { + netdev_err(dev, "rxnfc: user-def not supported\n"); + return -EINVAL; + } + } + + if ((cmd->fs.flow_type & FLOW_MAC_EXT)) { + /* don't allow mask which isn't valid */ + if (VALIDATE_MASK(cmd->fs.m_ext.h_dest)) { + netdev_err(dev, "rxnfc: Unsupported mask\n"); + return -EINVAL; + } + } + + return 0; +} + +static int bcmgenet_insert_flow(struct net_device *dev, + struct ethtool_rxnfc *cmd) +{ + struct bcmgenet_priv *priv = netdev_priv(dev); + struct bcmgenet_rxnfc_rule *loc_rule; + int err; + + if (priv->hw_params->hfb_filter_size < 128) { + netdev_err(dev, "rxnfc: Not supported by this device\n"); + return -EINVAL; + } + + if (cmd->fs.ring_cookie > priv->hw_params->rx_queues) { + netdev_err(dev, "rxnfc: Unsupported action (%llu)\n", + cmd->fs.ring_cookie); + return -EINVAL; + } + + err = bcmgenet_validate_flow(dev, cmd); + if (err) + return err; + + loc_rule = &priv->rxnfc_rules[cmd->fs.location]; + if (loc_rule->state == BCMGENET_RXNFC_STATE_ENABLED) + bcmgenet_hfb_disable_filter(priv, cmd->fs.location); + if (loc_rule->state != BCMGENET_RXNFC_STATE_UNUSED) + list_del(&loc_rule->list); + loc_rule->state = BCMGENET_RXNFC_STATE_UNUSED; + memcpy(&loc_rule->fs, &cmd->fs, + sizeof(struct ethtool_rx_flow_spec)); + + err = bcmgenet_hfb_create_rxnfc_filter(priv, loc_rule); + if (err) { + netdev_err(dev, "rxnfc: Could not install rule (%d)\n", + err); + return err; + } + + list_add_tail(&loc_rule->list, &priv->rxnfc_list); + + return 0; +} + +static int bcmgenet_delete_flow(struct net_device *dev, + struct ethtool_rxnfc *cmd) +{ + struct bcmgenet_priv *priv = netdev_priv(dev); + struct bcmgenet_rxnfc_rule *rule; + int err = 0; + + if (cmd->fs.location >= MAX_NUM_OF_FS_RULES) + return -EINVAL; + + rule = &priv->rxnfc_rules[cmd->fs.location]; + if (rule->state == BCMGENET_RXNFC_STATE_UNUSED) { + err = -ENOENT; + goto out; + } + + if (rule->state == BCMGENET_RXNFC_STATE_ENABLED) + bcmgenet_hfb_disable_filter(priv, cmd->fs.location); + if (rule->state != BCMGENET_RXNFC_STATE_UNUSED) + list_del(&rule->list); + rule->state = BCMGENET_RXNFC_STATE_UNUSED; + memset(&rule->fs, 0, sizeof(struct ethtool_rx_flow_spec)); + +out: + return err; +} + +static int bcmgenet_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) +{ + struct bcmgenet_priv *priv = netdev_priv(dev); + int err = 0; + + switch (cmd->cmd) { + case ETHTOOL_SRXCLSRLINS: + err = bcmgenet_insert_flow(dev, cmd); + break; + case ETHTOOL_SRXCLSRLDEL: + err = bcmgenet_delete_flow(dev, cmd); + break; + default: + netdev_warn(priv->dev, "Unsupported ethtool command. (%d)\n", + cmd->cmd); + return -EINVAL; + } + + return err; +} + +static int bcmgenet_get_flow(struct net_device *dev, struct ethtool_rxnfc *cmd, + int loc) +{ + struct bcmgenet_priv *priv = netdev_priv(dev); + struct bcmgenet_rxnfc_rule *rule; + int err = 0; + + if (loc < 0 || loc >= MAX_NUM_OF_FS_RULES) + return -EINVAL; + + rule = &priv->rxnfc_rules[loc]; + if (rule->state == BCMGENET_RXNFC_STATE_UNUSED) + err = -ENOENT; + else + memcpy(&cmd->fs, &rule->fs, + sizeof(struct ethtool_rx_flow_spec)); + + return err; +} + +static int bcmgenet_get_num_flows(struct bcmgenet_priv *priv) +{ + struct list_head *pos; + int res = 0; + + list_for_each(pos, &priv->rxnfc_list) + res++; + + return res; +} + +static int bcmgenet_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, + u32 *rule_locs) +{ + struct bcmgenet_priv *priv = netdev_priv(dev); + struct bcmgenet_rxnfc_rule *rule; + int err = 0; + int i = 0; + + switch (cmd->cmd) { + case ETHTOOL_GRXRINGS: + cmd->data = priv->hw_params->rx_queues ?: 1; + break; + case ETHTOOL_GRXCLSRLCNT: + cmd->rule_cnt = bcmgenet_get_num_flows(priv); + cmd->data = MAX_NUM_OF_FS_RULES; + break; + case ETHTOOL_GRXCLSRULE: + err = bcmgenet_get_flow(dev, cmd, cmd->fs.location); + break; + case ETHTOOL_GRXCLSRLALL: + list_for_each_entry(rule, &priv->rxnfc_list, list) + if (i < cmd->rule_cnt) + rule_locs[i++] = rule->fs.location; + cmd->rule_cnt = i; + cmd->data = MAX_NUM_OF_FS_RULES; + break; + default: + err = -EOPNOTSUPP; + break; + } + + return err; +} + /* standard ethtool support functions. */ static const struct ethtool_ops bcmgenet_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS | @@ -1221,6 +1667,8 @@ static const struct ethtool_ops bcmgenet_ethtool_ops = { .get_link_ksettings = bcmgenet_get_link_ksettings, .set_link_ksettings = bcmgenet_set_link_ksettings, .get_ts_info = ethtool_op_get_ts_info, + .get_rxnfc = bcmgenet_get_rxnfc, + .set_rxnfc = bcmgenet_set_rxnfc, }; /* Power down the unimac, based on mode. */ @@ -3730,8 +4178,8 @@ static int bcmgenet_resume(struct device *d) struct net_device *dev = dev_get_drvdata(d); struct bcmgenet_priv *priv = netdev_priv(dev); unsigned long dma_ctrl; + u32 offset, reg; int ret; - u32 reg; if (!netif_running(dev)) return 0; @@ -3766,6 +4214,11 @@ static int bcmgenet_resume(struct device *d) bcmgenet_set_hw_addr(priv, dev->dev_addr); + offset = HFB_FLT_ENABLE_V3PLUS; + bcmgenet_hfb_reg_writel(priv, priv->hfb_en[1], offset); + bcmgenet_hfb_reg_writel(priv, priv->hfb_en[2], offset + sizeof(u32)); + bcmgenet_hfb_reg_writel(priv, priv->hfb_en[0], HFB_CTRL); + if (priv->internal_phy) { reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); reg |= EXT_ENERGY_DET_MASK; @@ -3809,6 +4262,7 @@ static int bcmgenet_suspend(struct device *d) struct net_device *dev = dev_get_drvdata(d); struct bcmgenet_priv *priv = netdev_priv(dev); int ret = 0; + u32 offset; if (!netif_running(dev)) return 0; @@ -3820,6 +4274,13 @@ static int bcmgenet_suspend(struct device *d) if (!device_may_wakeup(d)) phy_suspend(dev->phydev); + /* Preserve filter state and disable filtering */ + priv->hfb_en[0] = bcmgenet_hfb_reg_readl(priv, HFB_CTRL); + offset = HFB_FLT_ENABLE_V3PLUS; + priv->hfb_en[1] = bcmgenet_hfb_reg_readl(priv, offset); + priv->hfb_en[2] = bcmgenet_hfb_reg_readl(priv, offset + sizeof(u32)); + bcmgenet_hfb_reg_writel(priv, 0, HFB_CTRL); + /* Prepare the device for Wake-on-LAN and switch to the slow clock */ if (device_may_wakeup(d) && priv->wolopts) ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index a858b7305832..031d91f45067 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -32,6 +32,7 @@ #define DMA_MAX_BURST_LENGTH 0x10 /* misc. configuration */ +#define MAX_NUM_OF_FS_RULES 16 #define CLEAR_ALL_HFB 0xFF #define DMA_FC_THRESH_HI (TOTAL_DESC >> 4) #define DMA_FC_THRESH_LO 5 @@ -609,6 +610,18 @@ struct bcmgenet_rx_ring { struct bcmgenet_priv *priv; }; +enum bcmgenet_rxnfc_state { + BCMGENET_RXNFC_STATE_UNUSED = 0, + BCMGENET_RXNFC_STATE_DISABLED, + BCMGENET_RXNFC_STATE_ENABLED +}; + +struct bcmgenet_rxnfc_rule { + struct list_head list; + struct ethtool_rx_flow_spec fs; + enum bcmgenet_rxnfc_state state; +}; + /* device context */ struct bcmgenet_priv { void __iomem *base; @@ -627,6 +640,8 @@ struct bcmgenet_priv { struct enet_cb *rx_cbs; unsigned int num_rx_bds; unsigned int rx_buf_len; + struct bcmgenet_rxnfc_rule rxnfc_rules[MAX_NUM_OF_FS_RULES]; + struct list_head rxnfc_list; struct bcmgenet_rx_ring rx_rings[DESC_INDEX + 1]; @@ -679,6 +694,7 @@ struct bcmgenet_priv { u32 wolopts; u8 sopass[SOPASS_MAX]; bool wol_active; + u32 hfb_en[3]; struct bcmgenet_mib_counters mib; From patchwork Wed Apr 29 20:02:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Berger X-Patchwork-Id: 1279624 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=oBv2dCRz; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49C8Yy6T9bz9sSj for ; Thu, 30 Apr 2020 06:02:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727783AbgD2UCW (ORCPT ); Wed, 29 Apr 2020 16:02:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57336 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726456AbgD2UCU (ORCPT ); Wed, 29 Apr 2020 16:02:20 -0400 Received: from mail-pf1-x442.google.com (mail-pf1-x442.google.com [IPv6:2607:f8b0:4864:20::442]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F8B3C03C1AE; Wed, 29 Apr 2020 13:02:20 -0700 (PDT) Received: by mail-pf1-x442.google.com with SMTP id y25so1598211pfn.5; Wed, 29 Apr 2020 13:02:20 -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; bh=J0qBpGmXm74u59PdUpmcex0+8Nx3UhOE65qV5C+byAc=; b=oBv2dCRzEE5SUc08jlC7HFjePmFYkPwvHD5/IS+AWIo5Hj3W/JNKm4rP5mho5lBsB0 yl9eAAJP6pnHwI/qpAB33pJfXMJsoGpQxG9robXKJX4aYLBmp6g7oCNa2sSqSCfdpXg5 PMzF9/3EZMEcNYOY3G24GSZhxJGKo6/DyWPlJ9ZCd4l1RUWT5IgCNk1OHB0ik6FuCDwr FJPmoyLSsZfHocKW0C9Bd+tTYLdrB0vKDph6TrOoaOIqPzyji5ev8cVrHqjbeFBeoMxa DIh1zSM+uPwTDAZfPAUVeGbQWolV3d/DcPDg/uVSMUFHQroQGA0zRnBPGoQbOlgLMLSs eScw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=J0qBpGmXm74u59PdUpmcex0+8Nx3UhOE65qV5C+byAc=; b=QaV/b9rKndJWphx5Oioop4OTbiBMUpoXIII3UJU2RlZMPIkTKiNZJa+YsvQGHJ5rIc 6tRWnq8N4tXMJeoSpKl5hMviaelxNW2jUTmvIaHzJStOZmZAIJaJIjtLenUBGAT3mU/o emhRKyyVIn+78gLjPHZVXD8A1xLSvIBbcZhNpA6D3VKGhPf+6RQE0ctLQcnKvo3WW43/ I3o+O2ubqwf8OiqdRjVHmBdAFLVXdHuKb31PAbmjDztbGD8974ebtyk1c0RMndEBmqot 9RV7gdkYSANZWdNdP2Bbh+R/P/9PMI0+JmzD/iKxVvM3v7A3rzianeU0bz8LVxLl9h+q xZ3w== X-Gm-Message-State: AGi0PubrXctt0YbH6sDnJPLgQqYlirtgzv7o32UT5A1+hd6LMbOqpcLi JrG7uYDrmH1w7+QtXNa3PtY= X-Google-Smtp-Source: APiQypJ02vjbrOILMgQC4AbLSwF3UAynZxs7gBl64GfniTmi0cwobVQHC5GRqDIhX+xh2L7NOZPj9w== X-Received: by 2002:a63:220a:: with SMTP id i10mr7162640pgi.364.1588190539755; Wed, 29 Apr 2020 13:02:19 -0700 (PDT) Received: from stbirv-lnx-3.igp.broadcom.net ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id r128sm1705817pfc.141.2020.04.29.13.02.18 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Apr 2020 13:02:18 -0700 (PDT) From: Doug Berger To: Florian Fainelli , "David S. Miller" Cc: bcm-kernel-feedback-list@broadcom.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Doug Berger Subject: [PATCH net-next v2 7/7] net: bcmgenet: add WAKE_FILTER support Date: Wed, 29 Apr 2020 13:02:06 -0700 Message-Id: <1588190526-2082-8-git-send-email-opendmb@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1588190526-2082-1-git-send-email-opendmb@gmail.com> References: <1588190526-2082-1-git-send-email-opendmb@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This commit enables support for the WAKE_FILTER method of Wake on LAN for the GENET driver. The method can be enabled by adding 'f' to the interface 'wol' setting specified by ethtool. Rx network flow rules can be specified using ethtool. Rules that define a flow-type with the RX_CLS_FLOW_WAKE action (i.e. -2) can wake the system from the 'standby' power state when the WAKE_FILTER WoL method is enabled. Signed-off-by: Doug Berger Acked-by: Florian Fainelli --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 5 ++- drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 43 +++++++++++++++++----- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 5ef1ea7e5312..ad614d7201bd 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -724,7 +724,7 @@ static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, break; } - if (!fs->ring_cookie) { + if (!fs->ring_cookie || fs->ring_cookie == RX_CLS_FLOW_WAKE) { /* Ring 0 flows can be handled by the default Descriptor Ring * We'll map them to ring 0, but don't enable the filter */ @@ -1499,7 +1499,8 @@ static int bcmgenet_insert_flow(struct net_device *dev, return -EINVAL; } - if (cmd->fs.ring_cookie > priv->hw_params->rx_queues) { + if (cmd->fs.ring_cookie > priv->hw_params->rx_queues && + cmd->fs.ring_cookie != RX_CLS_FLOW_WAKE) { netdev_err(dev, "rxnfc: Unsupported action (%llu)\n", cmd->fs.ring_cookie); return -EINVAL; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c index da45a4645b94..4b9d65f392c2 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c @@ -42,7 +42,7 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct bcmgenet_priv *priv = netdev_priv(dev); - wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE; + wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER; wol->wolopts = priv->wolopts; memset(wol->sopass, 0, sizeof(wol->sopass)); @@ -61,7 +61,7 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (!device_can_wakeup(kdev)) return -ENOTSUPP; - if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE)) + if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER)) return -EINVAL; if (wol->wolopts & WAKE_MAGICSECURE) @@ -117,8 +117,9 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, enum bcmgenet_power_mode mode) { struct net_device *dev = priv->dev; + struct bcmgenet_rxnfc_rule *rule; + u32 reg, hfb_ctrl_reg, hfb_enable = 0; int retries = 0; - u32 reg; if (mode != GENET_POWER_WOL_MAGIC) { netif_err(priv, wol, dev, "unsupported mode: %d\n", mode); @@ -135,13 +136,24 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, bcmgenet_umac_writel(priv, reg, UMAC_CMD); mdelay(10); - reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); - reg |= MPD_EN; - if (priv->wolopts & WAKE_MAGICSECURE) { - bcmgenet_set_mpd_password(priv); - reg |= MPD_PW_EN; + if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) { + reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); + reg |= MPD_EN; + if (priv->wolopts & WAKE_MAGICSECURE) { + bcmgenet_set_mpd_password(priv); + reg |= MPD_PW_EN; + } + bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); + } + + hfb_ctrl_reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL); + if (priv->wolopts & WAKE_FILTER) { + list_for_each_entry(rule, &priv->rxnfc_list, list) + if (rule->fs.ring_cookie == RX_CLS_FLOW_WAKE) + hfb_enable |= (1 << rule->fs.location); + reg = (hfb_ctrl_reg & ~RBUF_HFB_EN) | RBUF_ACPI_EN; + bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL); } - bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); /* Do not leave UniMAC in MPD mode only */ retries = bcmgenet_poll_wol_status(priv); @@ -149,6 +161,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); reg &= ~(MPD_EN | MPD_PW_EN); bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); + bcmgenet_hfb_reg_writel(priv, hfb_ctrl_reg, HFB_CTRL); return retries; } @@ -158,6 +171,13 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, clk_prepare_enable(priv->clk_wol); priv->wol_active = 1; + if (hfb_enable) { + bcmgenet_hfb_reg_writel(priv, hfb_enable, + HFB_FLT_ENABLE_V3PLUS + 4); + hfb_ctrl_reg = RBUF_HFB_EN | RBUF_ACPI_EN; + bcmgenet_hfb_reg_writel(priv, hfb_ctrl_reg, HFB_CTRL); + } + /* Enable CRC forward */ reg = bcmgenet_umac_readl(priv, UMAC_CMD); priv->crc_fwd_en = 1; @@ -197,6 +217,11 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv, reg &= ~(MPD_EN | MPD_PW_EN); bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); + /* Disable WAKE_FILTER Detection */ + reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL); + reg &= ~(RBUF_HFB_EN | RBUF_ACPI_EN); + bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL); + /* Disable CRC Forward */ reg = bcmgenet_umac_readl(priv, UMAC_CMD); reg &= ~CMD_CRC_FWD;