From patchwork Tue Oct 16 18:20:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 148980 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp5435114lji; Tue, 16 Oct 2018 11:20:47 -0700 (PDT) X-Google-Smtp-Source: ACcGV63fs35HRF4k21U65SoZ6YNjDBtjbEMMefWDYRh3RVfkK8syNWy6M57GYXe0TeLUIzPkiVcz X-Received: by 2002:a62:178f:: with SMTP id 137-v6mr22524082pfx.215.1539714047617; Tue, 16 Oct 2018 11:20:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539714047; cv=none; d=google.com; s=arc-20160816; b=OFOALzXZIf2kFFvmuW6ZnsUZvPRyvaGUmGdPrtZ1PQ0y+F9bV+OK7jBAXXQ91n19AD h53UZiYImuA25Zui3KcI9SV74SwPhukgLx2NaMttK9JcQrBMbNkHdahSabu3O6x1RxmA 63AImMC1X6BmDfzDESWYSCZzCBFN6gAwzT5RK5wHySSibNVPf+y7482xrsUU9bIsZCCO P4QmpuhXjiYlW5eWxHQ3WL3dqlRrlHStLE7viOPGIJ/k1H4M6yP86d9r21rEd7uQ70Aq VqQyFnKg8y26gS75EKMeJZ+4qhravKpGSxcxqE6Rha8vovoD/D/YPIbNY2iMKYk/nC0m tYqQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=jLFuOs1cSVmlpobA1RYDVi6svvbcni9hZ6eXt8GSdXw=; b=iYYBid531LA5LP/OceXez/sY0MOUo3fCUS0nQG63mcvoYHZMmTGeKi6KCxwVs1VDqp ITkkT4YsgmVwI6oUUHwGToJnE2GhYWNUxk/X9bayw0Jn+Ud8dq3cruJ3lIkQyYGMxsUu 9Suo2DT9lxGkyQKL/agCWfIgMYEIQcLnprn3sbbEDvwerxpBav9pSPD4gKd82YP81LiB X60uxm5NuokRlBebDKLcxkRufIRZnM5jhT3V8ONYeSEK3cF7MjnD4s/feBUm3Xl5fKSN f3JgxOsNpzwAgCFFLX8lYUB7DW+KgQBxG7Y2qfL9irFzXdJvnq2hvFqWUzmfOYSF+bxB EUKg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FIaiTraV; spf=pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 202-v6si13653070pgb.63.2018.10.16.11.20.47; Tue, 16 Oct 2018 11:20:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FIaiTraV; spf=pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727608AbeJQCMZ (ORCPT + 10 others); Tue, 16 Oct 2018 22:12:25 -0400 Received: from mail-lf1-f66.google.com ([209.85.167.66]:37941 "EHLO mail-lf1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727528AbeJQCMZ (ORCPT ); Tue, 16 Oct 2018 22:12:25 -0400 Received: by mail-lf1-f66.google.com with SMTP id x24-v6so1985103lfe.5 for ; Tue, 16 Oct 2018 11:20:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jLFuOs1cSVmlpobA1RYDVi6svvbcni9hZ6eXt8GSdXw=; b=FIaiTraVPXrqdoxh0HtJYKo8IhE+QVgs/NViyyoegt8hW2EPcAxXZMPTuP2KuIXD88 NLSCnk4RKWh4pG8tXs4ksgTJrb0A1ldbAv9u6IzOzhhQEg/VgitiZ7OnIS1viy3ODBzh wid/HPjpypVB2SjsbdCh0RON1srP7cKDGD9yg= 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=jLFuOs1cSVmlpobA1RYDVi6svvbcni9hZ6eXt8GSdXw=; b=btRGjRE5EuHDBJydBT72iGGPIxeU41vs9vPI/7be9ZGFFYlmSvOhrZGY1w3oq8kh/B dKGsEGesKD715RvGBquxrc3j2hxePyIJI2Wpbl1xGHkpbkLkYZ7JDViDVHpbRVXNxcID Urz78lJD4rrMYYdzDvLlsw/wos6Le4IFMLKOIiJwz/eCiNLY0VL80POBA44Ar01qj15H nH0viPVi5q7gXuTXu982w/+kAWIgFfhM9uU+1mF6h6x+OKhBIoc4UaQIeStV8S75aP9A pm1Qusz+HDoV5MOntVCXm1wVvBrBGhvfoqHTz05k7FKQyZVcykBI5SkTO9m4IP+HlFl/ Cxsg== X-Gm-Message-State: ABuFfohuzzy6tIt7hCrHa3+UkZ3DtO6aYhyxQy7maYGj7A/B4RSj7gsW 34/TfnLAIOTmtGZHk8Krc93akQaEaMQ= X-Received: by 2002:a19:d713:: with SMTP id o19-v6mr13078188lfg.114.1539714042680; Tue, 16 Oct 2018 11:20:42 -0700 (PDT) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id i27-v6sm3207844lfc.22.2018.10.16.11.20.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Oct 2018 11:20:41 -0700 (PDT) From: Ivan Khoronzhuk To: grygorii.strashko@ti.com, davem@davemloft.net Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexander.h.duyck@intel.com, Ivan Khoronzhuk Subject: [RFC PATCH net-next 3/4] net: ethernet: ti: cpsw: fix vlan mcast Date: Tue, 16 Oct 2018 21:20:34 +0300 Message-Id: <20181016182035.18234-4-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181016182035.18234-1-ivan.khoronzhuk@linaro.org> References: <20181016182035.18234-1-ivan.khoronzhuk@linaro.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org At this moment, mcast addresses are added only for real device only (reserved vlans for dual-emac mode), even if a mcast address was added for some vlan only, thus ALE doesn't have corresponding vlan mcast entries after vlan socket joined multicast group. So ALE drops vlan frames with mcast addresses intended for vlans and potentially can receive mcast frames for base ndev. That's not correct. So, fix it by creating only vlan/mcast entries as requested. Patch doesn't use any additional lists and is based on device mc address list and cpsw ALE table entries. Also, move device to allmulti state if no space for new mcast entries. Signed-off-by: Ivan Khoronzhuk --- drivers/net/ethernet/ti/cpsw.c | 172 +++++++++++++++++++++++++++------ 1 file changed, 142 insertions(+), 30 deletions(-) -- 2.17.1 diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 226be2a56c1f..5967484619d4 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -570,21 +570,6 @@ static inline int cpsw_get_slave_port(u32 slave_num) return slave_num + 1; } -static void cpsw_add_mcast(struct cpsw_priv *priv, const u8 *addr) -{ - struct cpsw_common *cpsw = priv->cpsw; - - if (cpsw->data.dual_emac) { - struct cpsw_slave *slave = cpsw->slaves + priv->emac_port; - - cpsw_ale_add_mcast(cpsw->ale, addr, ALE_PORT_HOST, - ALE_VLAN, slave->port_vlan, 0); - return; - } - - cpsw_ale_add_mcast(cpsw->ale, addr, ALE_ALL_PORTS, 0, 0, 0); -} - static void cpsw_set_promiscious(struct net_device *ndev, bool enable) { struct cpsw_common *cpsw = ndev_to_cpsw(ndev); @@ -660,29 +645,153 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) } } -static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr) +struct addr_sync_ctx { + struct net_device *ndev; + const u8 *addr; /* address to be sync or unsync */ + int keep_num; /* number of address instances to be kept */ + int flush; /* flush flag */ +}; + +/** + * cpsw_set_mc - adds multicast entry to the table if it's not added or deletes + * if it's not deleted + * @ndev: device to sync + * @addr: address to be added or deleted + * @vid: vlan id, if vid < 0 set/unset address for real device + * @add: add address if the flag is set or remove otherwise + */ +static int cpsw_set_mc(struct net_device *ndev, const u8 *addr, + int vid, int add) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; + int mask, flags, ret; + + if (vid < 0) { + if (cpsw->data.dual_emac) + vid = cpsw->slaves[priv->emac_port].port_vlan; + else + vid = 0; + } + + mask = cpsw->data.dual_emac ? ALE_PORT_HOST : ALE_ALL_PORTS; + flags = vid ? ALE_VLAN : 0; + + if (add) + ret = cpsw_ale_add_mcast(cpsw->ale, addr, mask, flags, vid, 0); + else + ret = cpsw_ale_del_mcast(cpsw->ale, addr, 0, flags, vid); + + return ret; +} + +static int cpsw_update_vlan_mc(struct net_device *vdev, int vid, void *ctx) +{ + struct addr_sync_ctx *sync_ctx = ctx; + struct netdev_hw_addr *ha; + int found = 0, ret = 0; + + if (!vdev || !(vdev->flags & IFF_UP)) + return ret; + + /* vlan address is relevant if it's sync_cnt != 0 */ + netdev_for_each_mc_addr(ha, vdev) { + if (ether_addr_equal(ha->addr, sync_ctx->addr)) { + found = ha->sync_cnt; + break; + } + } + + if (found) + sync_ctx->keep_num--; + + if (sync_ctx->flush) { + if (!found) + cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 0); + return ret; + } + + if (found) + ret = cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 1); + + return ret; +} + +static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr, int num) +{ + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); + struct addr_sync_ctx sync_ctx; + int ret; + + sync_ctx.keep_num = num; + sync_ctx.addr = addr; + sync_ctx.ndev = ndev; + sync_ctx.flush = 0; + + ret = vlan_for_each(ndev, cpsw_update_vlan_mc, &sync_ctx); + if (sync_ctx.keep_num && !ret) + ret = cpsw_set_mc(ndev, addr, -1, 1); + + /* table is overflowed, set ALLMULTI */ + if (ret == -ENOMEM) + cpsw_ale_set_allmulti(cpsw->ale, IFF_ALLMULTI); + + return ret; +} + +static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr, int num) +{ + struct addr_sync_ctx sync_ctx; + + sync_ctx.keep_num = num; + sync_ctx.addr = addr; + sync_ctx.ndev = ndev; + sync_ctx.flush = 1; + + vlan_for_each(ndev, cpsw_update_vlan_mc, &sync_ctx); + if (!sync_ctx.keep_num) + cpsw_set_mc(ndev, addr, -1, 0); - cpsw_add_mcast(priv, addr); return 0; } -static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr) +static int cpsw_purge_vlan_mc(struct net_device *vdev, int vid, void *ctx) { - struct cpsw_priv *priv = netdev_priv(ndev); - struct cpsw_common *cpsw = priv->cpsw; - int vid, flags; + struct addr_sync_ctx *sync_ctx = ctx; + struct netdev_hw_addr *ha; + int found = 0; - if (cpsw->data.dual_emac) { - vid = cpsw->slaves[priv->emac_port].port_vlan; - flags = ALE_VLAN; - } else { - vid = 0; - flags = 0; + if (!vdev || !(vdev->flags & IFF_UP)) + return 0; + + /* vlan address is relevant if it's sync_cnt != 0 */ + netdev_for_each_mc_addr(ha, vdev) { + if (ether_addr_equal(ha->addr, sync_ctx->addr)) { + found = ha->sync_cnt; + break; + } } - cpsw_ale_del_mcast(cpsw->ale, addr, 0, flags, vid); + if (!found) + return 0; + + sync_ctx->keep_num--; + cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 0); + return 0; +} + +static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num) +{ + struct addr_sync_ctx sync_ctx; + + sync_ctx.addr = addr; + sync_ctx.ndev = ndev; + sync_ctx.keep_num = num; + + vlan_for_each(ndev, cpsw_purge_vlan_mc, &sync_ctx); + if (sync_ctx.keep_num) + cpsw_set_mc(ndev, addr, -1, 0); + return 0; } @@ -703,7 +812,9 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) /* Restore allmulti on vlans if necessary */ cpsw_ale_set_allmulti(cpsw->ale, ndev->flags & IFF_ALLMULTI); - __dev_mc_sync(ndev, cpsw_add_mc_addr, cpsw_del_mc_addr); + /* add/remove mcast address either for real netdev or for vlan */ + __hw_addr_ref_sync_dev(&ndev->mc, ndev, cpsw_add_mc_addr, + cpsw_del_mc_addr); } static void cpsw_intr_enable(struct cpsw_common *cpsw) @@ -1963,7 +2074,7 @@ static int cpsw_ndo_stop(struct net_device *ndev) struct cpsw_common *cpsw = priv->cpsw; cpsw_info(priv, ifdown, "shutting down cpsw device\n"); - __dev_mc_unsync(priv->ndev, cpsw_del_mc_addr); + __hw_addr_ref_unsync_dev(&ndev->mc, ndev, cpsw_purge_all_mc); netif_tx_stop_all_queues(priv->ndev); netif_carrier_off(priv->ndev); @@ -2414,6 +2525,7 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, HOST_PORT_NUM, ALE_VLAN, vid); ret |= cpsw_ale_del_mcast(cpsw->ale, priv->ndev->broadcast, 0, ALE_VLAN, vid); + ret |= cpsw_ale_flush_multicast(cpsw->ale, 0, vid); err: pm_runtime_put(cpsw->dev); return ret; From patchwork Tue Oct 16 18:20:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 148981 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp5435131lji; Tue, 16 Oct 2018 11:20:48 -0700 (PDT) X-Google-Smtp-Source: ACcGV61txXDjLlF0CzZA3qhCMgyGS3FaG2lL3KLlyU/K2rnh/GALAympoKOitHL3Bfvh2eMEovVR X-Received: by 2002:a62:8145:: with SMTP id t66-v6mr22533889pfd.192.1539714048495; Tue, 16 Oct 2018 11:20:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539714048; cv=none; d=google.com; s=arc-20160816; b=DerUvWUFanBtenWkrjHAzN0Fs+yMWUzFUBGbGkqepf9W8RaFbAcjSHlgBALvJWc4vG PbH7B0uB+EW/we2pTFNPLFDfgudbjoNRoWzuET0WqugKIvXQAhQZQWTV7J7ph+rGbR70 t8IOkt8HKvpYcWfYTENDL/LbuZXxLVU4kf/i7e547AxqjDBISV9vv75VLfVuD9XpwFY7 n7LVvCU3EMI647IamQhno8wbw6qWqBcCDtqt4SQUSrcBqfu6+3lswH6HcZpTwfqo4CKY +CE67AfMz8C9oZ/95f5n66TNYxPLO0ZLUYXe+CYhh9t52h+lAUAU7ERSFYS8QbnyawcE erBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=ssuygcYMLn1Q3WIghGGutlJDCYEv/K27yRAinbSWkn0=; b=zvZj5lklJmr+EGtSUvwqfFmeIR+tK30KiZ/kZtubfGGCcZqX1JaLYRqmvKgW0ebgaC ZIOpbfdbjdumzACxI44rP80zitaTM8VCP05Jsnj+ncb2wh4holGUnghrG16B4oITsWY1 acHx9eFfNIE8oImZ9jCTS9rBPBDivV+Z5z9OMHIlp8DsbaFG6xPOoVpG0GpFeGk2wPM6 VlpGJAFyBECMqEAiO/7+ltIDHu5NMGy2sJ9brCXIBXo0dpPZwFaU5NWwaRK61AdV5Xik 9tpvWMMQhMuCOdPmEfvi1KyMqWMc9CHyV3qMoSzXjSPW11QsQcNmOj4ZnsH5EESCKZI+ NGiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SVgLBgPN; spf=pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 202-v6si13653070pgb.63.2018.10.16.11.20.48; Tue, 16 Oct 2018 11:20:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SVgLBgPN; spf=pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727615AbeJQCM1 (ORCPT + 10 others); Tue, 16 Oct 2018 22:12:27 -0400 Received: from mail-lf1-f66.google.com ([209.85.167.66]:39284 "EHLO mail-lf1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727160AbeJQCM1 (ORCPT ); Tue, 16 Oct 2018 22:12:27 -0400 Received: by mail-lf1-f66.google.com with SMTP id n14-v6so5884542lfe.6 for ; Tue, 16 Oct 2018 11:20:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ssuygcYMLn1Q3WIghGGutlJDCYEv/K27yRAinbSWkn0=; b=SVgLBgPNL/Sitz1phBzvx86rsDjysgDcl4zkZoW8vR7l04xha37TWN57++dA+Z7tbG 8a62jDyS2L1Cmn1YBDyC8OBpIl6Sy83zj1YANM8LCJN9L7KJE56gjxwSuXKVXYISoQq7 HoWglV34ppwNd8C53EhQe0LRiHB1zASMCaoqc= 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=ssuygcYMLn1Q3WIghGGutlJDCYEv/K27yRAinbSWkn0=; b=ru0dzNk1cXrB8sg6omnzf7VjkjyhmWysgMM/aT7vo2qewIVnFxfrJJ7pXfz3VgbSra ZQMVYCNsZ+HarBAT9NiOIrIwZ99+yxoj/U/8LAlJ3y1i8yl/UZtgwVGVTGfjx2jfhonI KBx7q0fmClDN3b2+BMLhBR71VhLYdDSo8AGAdVvwmTqa9SnMzZpkjibftmSZct6C4mKv wJNwv1tKY5/fkYrMGXp0Nq9OLKp+EXNFrr3dV6ZVV6/gMfQMlGq6asoz+N2a7NvjA+E9 8T47ofCQHltoUuwLd51a2B+nbS7buD9OcqixXU73/K6L8SRR3QB7BL7XSNy9TqTmaHsp pOwg== X-Gm-Message-State: ABuFfojZWf1aoumAx6R8WYlbQa7f2UecVeRptinsFl7Bu8zjcsTsIRBU +j3mxxtECDYua+BJUTl5DQ7/dA== X-Received: by 2002:a19:d3c4:: with SMTP id k187-v6mr13953987lfg.101.1539714044045; Tue, 16 Oct 2018 11:20:44 -0700 (PDT) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id i27-v6sm3207844lfc.22.2018.10.16.11.20.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Oct 2018 11:20:43 -0700 (PDT) From: Ivan Khoronzhuk To: grygorii.strashko@ti.com, davem@davemloft.net Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexander.h.duyck@intel.com, Ivan Khoronzhuk Subject: [RFC PATCH net-next 4/4] net: ethernet: ti: cpsw: fix vlan configuration while down/up Date: Tue, 16 Oct 2018 21:20:35 +0300 Message-Id: <20181016182035.18234-5-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181016182035.18234-1-ivan.khoronzhuk@linaro.org> References: <20181016182035.18234-1-ivan.khoronzhuk@linaro.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The vlan configuration is not restored after interface donw/up sequence (if dual-emac - both interfaces). Tested on am572x EVM. Steps to check: ~# ip link add link eth1 name eth1.100 type vlan id 100 ~# ifconfig eth0 down ~# ifconfig eth1 down This is TI sdk tool, dumping all ALE entries, see they are present ~# switch-config -d ~# ifconfig eth1 up See entry for vid 100 is absent ~# switch-config -d Try to remove vid and observe warning: ~# ip link del eth1.100 [ 739.526757] net eth1: removing vlanid 100 from vlan filter [ 739.533322] failed to kill vid 0081/100 for device eth1 This patch fixes it, restoring only vlan ALE entries and all other unicast/multicast entries are restored by system calling rx_mode ndo. Signed-off-by: Ivan Khoronzhuk --- drivers/net/ethernet/ti/cpsw.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) -- 2.17.1 diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 5967484619d4..0b28a90b62bb 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -565,6 +565,9 @@ static const struct cpsw_stats cpsw_gstrings_ch_stats[] = { (func)(slave++, ##arg); \ } while (0) +static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, + __be16 proto, u16 vid); + static inline int cpsw_get_slave_port(u32 slave_num) { return slave_num + 1; @@ -1955,9 +1958,23 @@ static void cpsw_mqprio_resume(struct cpsw_slave *slave, struct cpsw_priv *priv) slave_write(slave, tx_prio_map, tx_prio_rg); } +static int cpsw_restore_vlans(struct net_device *vdev, int vid, void *arg) +{ + struct cpsw_priv *priv = arg; + + if (!vdev) + return 0; + + cpsw_ndo_vlan_rx_add_vid(priv->ndev, 0, vid); + return 0; +} + /* restore resources after port reset */ static void cpsw_restore(struct cpsw_priv *priv) { + /* restore vlan configurations */ + vlan_for_each(priv->ndev, cpsw_restore_vlans, priv); + /* restore MQPRIO offload */ for_each_slave(priv, cpsw_mqprio_resume, priv);