From patchwork Tue Feb 26 18:45:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 159240 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp3545630jad; Tue, 26 Feb 2019 10:47:13 -0800 (PST) X-Google-Smtp-Source: AHgI3Ia/WTdFy78JoocgPDbEfsKRl46a8X89hOdBNSL20+y8KbKNql08JhXXuRaA0d3n9Ju/KpnQ X-Received: by 2002:a62:33c1:: with SMTP id z184mr27272000pfz.104.1551206833544; Tue, 26 Feb 2019 10:47:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551206833; cv=none; d=google.com; s=arc-20160816; b=ZTeIAG5FVMuXBdRq7R1FVSh03mrmquFz3l2dPIHuDXeROoc9pUjat4ZgtYSLg+nqoX NyX31Tl62ja8hiZINE9WZffrlVS5tbJrpVnK20xJh4Ufry6HkZDrzDyPu/gQI4UnYhAl aSIHhZf5cXX6W9qJ0ssX1YVwLVT/VnU3gDX6MXoFLJeo9sZTZDwH1p4danfbnbrwyffP vBzL5IJTSWM3SyEDYFBV0wqCbjC5l0zI5AtNDpfd4my0YQU+3va1r4ZwX+kKSw2W5sCS RWf6g41hFB+K6L9ja9KtUVBUQrhCVNNact5YsXXujlpKIIw4Lr/9eXGaMBryX5fqIz29 q/+g== 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=DcDw7IrxqjOxRf2I8tQwrAbV9hm03kKacBat2OiHhV8=; b=dWxzjW9eA8Uqc53zqtTxVcFNJMUTkLkL4bZjWwmWvRv9670gdpd1aAUmlKj7AXvjXe QxsVndPcsj4aqxpAWlq7r8LbKtBBPt+GCBXrSPtzgkOnOw0gsp+GfCQ37+QBcCWTBVCt 0GY4Ov37Sy4nMbWqH4aA3KdPhsaIXBGbyOlKYHYFBPorkeU86coC0EuiLytVd5w1/ErK pSxb8JOvgFr69HZbeanwfAFVvEzYCVaNMCkqYU7FYky6NjeCb0jP6bhHTy+5Ij3qgBSJ KBBb5uhm1/QVYK7SZX9QKE0dgxnOUpQQXhemRcpGx6hedjtZVCb3hwYfk0Y+sdn5UPni /rvg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=fGy464fU; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f2si11196228pgl.30.2019.02.26.10.47.13; Tue, 26 Feb 2019 10:47:13 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=fGy464fU; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729337AbfBZSrL (ORCPT + 31 others); Tue, 26 Feb 2019 13:47:11 -0500 Received: from mail-lf1-f67.google.com ([209.85.167.67]:37079 "EHLO mail-lf1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729109AbfBZSqd (ORCPT ); Tue, 26 Feb 2019 13:46:33 -0500 Received: by mail-lf1-f67.google.com with SMTP id z196so9744220lff.4 for ; Tue, 26 Feb 2019 10:46:30 -0800 (PST) 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=DcDw7IrxqjOxRf2I8tQwrAbV9hm03kKacBat2OiHhV8=; b=fGy464fUWN2DY6G0KVw5uTrWDyl77JIUOm4Z9OOb3mluFGnXqneATfRFC2hVcqz9s5 B8vaorp5AihQbJsjaWf1QjmOeY8m9oYAARRuKhl5uJWsxitjDCw0JVt2rlc0DKp6GYQ1 gI72LtJlpTOXsk2aVhQPkRDTRVBnCV7B5KxyJJ4Qt1Iz7esmXtsKTHmjz8sA0JldvZcT FZjdvxegiVOMmf6WJJ4iia1+0E1m2TxB6nNsWxzBrhxohlMCiix/f/oF5UwdBL7fLp+2 A+bLACUJJcs+ql6tXaVfUMZ3UeMtORsXS1EuiVfrTkbhcsV+alcuxyPB45zgv5Rp9Ay2 jQkw== 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=DcDw7IrxqjOxRf2I8tQwrAbV9hm03kKacBat2OiHhV8=; b=K6p+fhsXQ3CxGCgSuTRXkXYrSq4J87UeJqdg5wTu8ip7IdjASAS1/AGfiJwkhQnyE4 v3DB4t6n1nOqWT2w8hRBZNkQv3jsM6zcq4KKGC7iqmIa16Mp1Kin8XyQEP94j77aXkar asIAWq81OIyq1pBiic+wSotvvu/3fEDigS7Ka68suErSxT3t2AOBiq0BqdQPR6IdzW7x +eiEJ27X+c2IdUXRMYm+Kb5oOrcJ1lknfksVW5pER1cyK5gGFZbdxcTHR6gOwCZgFIn8 sigo17rvY5fVP3241ibI/TGu8N/aLlxlaIteSx77b87h5iVTsUrGi/YXjYi5xH/SVLkp 6tYw== X-Gm-Message-State: AHQUAua06S1tiGA1fQFLk0iSzDJrC+Z0f/m+bl4+3LDh8qu9gYsP+viI WPulnDp/W9Wh+SEbQlIrGNmWhisv5Ag= X-Received: by 2002:a19:d411:: with SMTP id l17mr1323106lfg.112.1551206789404; Tue, 26 Feb 2019 10:46:29 -0800 (PST) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id s129sm3015190lja.49.2019.02.26.10.46.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Feb 2019 10:46:28 -0800 (PST) From: Ivan Khoronzhuk To: davem@davemloft.net, grygorii.strashko@ti.com, f.fainelli@gmail.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jiri@mellanox.com, ilias.apalodimas@linaro.org, Ivan Khoronzhuk Subject: [PATCH net-next 1/6] net: core: dev_addr_lists: add VID to device address Date: Tue, 26 Feb 2019 20:45:51 +0200 Message-Id: <20190226184556.16082-2-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190226184556.16082-1-ivan.khoronzhuk@linaro.org> References: <20190226184556.16082-1-ivan.khoronzhuk@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Despite this is supposed to be used for Ethernet VLANs, not Ethernet addresses with space for VID also can reuse this, so VID is considered as virtual ID extension, not belonging strictly to Ethernet VLAN VIDs, and overall change can be named individual virtual device filtering (IVDF). This patch adds VID tag at the end of each address. The actual reserved address size is 32 bytes. For Ethernet addresses with 6 bytes long that's possible to add tag w/o increasing address size. Thus, each address for the case has 32 - 6 = 26 bytes to hold additional info, say VID for virtual device addresses. Therefore, when addresses are synced to the address list of parent device the address list of latter can contain separate addresses for virtual devices. It allows to track separate address tables for virtual devices if they present and the device can be placed on any place of device tree as the address is propagated to to the end real device thru *_sync()/ndo_set_rx_mode() APIs. Also it simplifies handling VID addresses at real device when it supports IVDF. If parent device doesn't want to have virtual addresses in its address space the vid_len has to be 0, thus its address space is "shrunk" to the state as before this patch. For now it's 0 for every device. It allows two devices with and w/o IVDF to be part of same bond device for instance. The end real device supporting IVDF can retrieve VID tag from an address and set it for a given virtual device only. By default, vid 0 is used for real devices to distinguish it from virtual addresses. See next patches to see how it's used. Signed-off-by: Ivan Khoronzhuk --- include/linux/netdevice.h | 4 ++ net/core/dev_addr_lists.c | 124 +++++++++++++++++++++++++++++++------- 2 files changed, 105 insertions(+), 23 deletions(-) -- 2.17.1 diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 58e83bd7a861..74fef35b6bec 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1660,6 +1660,7 @@ enum netdev_priv_flags { * @perm_addr: Permanent hw address * @addr_assign_type: Hw address assignment type * @addr_len: Hardware address length + * @vid_len: Virtual ID length, set in case of IVDF * @neigh_priv_len: Used in neigh_alloc() * @dev_id: Used to differentiate devices that share * the same link layer address @@ -1889,6 +1890,7 @@ struct net_device { unsigned char perm_addr[MAX_ADDR_LEN]; unsigned char addr_assign_type; unsigned char addr_len; + unsigned char vid_len; unsigned short neigh_priv_len; unsigned short dev_id; unsigned short dev_port; @@ -4141,8 +4143,10 @@ int dev_addr_init(struct net_device *dev); /* Functions used for unicast addresses handling */ int dev_uc_add(struct net_device *dev, const unsigned char *addr); +int dev_vid_uc_add(struct net_device *dev, const unsigned char *addr); int dev_uc_add_excl(struct net_device *dev, const unsigned char *addr); int dev_uc_del(struct net_device *dev, const unsigned char *addr); +int dev_vid_uc_del(struct net_device *dev, const unsigned char *addr); int dev_uc_sync(struct net_device *to, struct net_device *from); int dev_uc_sync_multiple(struct net_device *to, struct net_device *from); void dev_uc_unsync(struct net_device *to, struct net_device *from); diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index a6723b306717..e3c80e044b8c 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -545,6 +545,26 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr, } EXPORT_SYMBOL(dev_addr_del); +static int get_addr_len(struct net_device *dev) +{ + return dev->addr_len + dev->vid_len; +} + +static int set_vid_addr(struct net_device *dev, const unsigned char *addr, + unsigned char *naddr) +{ + int i; + + if (!dev->vid_len) + return dev->addr_len; + + memcpy(naddr, addr, dev->addr_len); + for (i = 0; i < dev->vid_len; i++) + naddr[dev->addr_len + i] = 0; + + return get_addr_len(dev); +} + /* * Unicast list handling functions */ @@ -556,18 +576,22 @@ EXPORT_SYMBOL(dev_addr_del); */ int dev_uc_add_excl(struct net_device *dev, const unsigned char *addr) { + unsigned char naddr[MAX_ADDR_LEN]; struct netdev_hw_addr *ha; - int err; + int addr_len, err; + + addr_len = set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; netif_addr_lock_bh(dev); list_for_each_entry(ha, &dev->uc.list, list) { - if (!memcmp(ha->addr, addr, dev->addr_len) && + if (!memcmp(ha->addr, addr, addr_len) && ha->type == NETDEV_HW_ADDR_T_UNICAST) { err = -EEXIST; goto out; } } - err = __hw_addr_create_ex(&dev->uc, addr, dev->addr_len, + err = __hw_addr_create_ex(&dev->uc, addr, addr_len, NETDEV_HW_ADDR_T_UNICAST, true, false); if (!err) __dev_set_rx_mode(dev); @@ -578,47 +602,89 @@ int dev_uc_add_excl(struct net_device *dev, const unsigned char *addr) EXPORT_SYMBOL(dev_uc_add_excl); /** - * dev_uc_add - Add a secondary unicast address + * dev_vid_uc_add - Add a secondary unicast address with tag * @dev: device - * @addr: address to add + * @addr: address to add, includes vid tag already * * Add a secondary unicast address to the device or increase * the reference count if it already exists. */ -int dev_uc_add(struct net_device *dev, const unsigned char *addr) +int dev_vid_uc_add(struct net_device *dev, const unsigned char *addr) { int err; netif_addr_lock_bh(dev); - err = __hw_addr_add(&dev->uc, addr, dev->addr_len, + err = __hw_addr_add(&dev->uc, addr, get_addr_len(dev), NETDEV_HW_ADDR_T_UNICAST); if (!err) __dev_set_rx_mode(dev); netif_addr_unlock_bh(dev); return err; } +EXPORT_SYMBOL(dev_vid_uc_add); + +/** + * dev_uc_add - Add a secondary unicast address + * @dev: device + * @addr: address to add + * + * Add a secondary unicast address to the device or increase + * the reference count if it already exists. + */ +int dev_uc_add(struct net_device *dev, const unsigned char *addr) +{ + unsigned char naddr[MAX_ADDR_LEN]; + int err; + + set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; + + err = dev_vid_uc_add(dev, addr); + return err; +} EXPORT_SYMBOL(dev_uc_add); /** * dev_uc_del - Release secondary unicast address. * @dev: device - * @addr: address to delete + * @addr: address to delete, includes vid tag already * * Release reference to a secondary unicast address and remove it * from the device if the reference count drops to zero. */ -int dev_uc_del(struct net_device *dev, const unsigned char *addr) +int dev_vid_uc_del(struct net_device *dev, const unsigned char *addr) { int err; netif_addr_lock_bh(dev); - err = __hw_addr_del(&dev->uc, addr, dev->addr_len, + err = __hw_addr_del(&dev->uc, addr, get_addr_len(dev), NETDEV_HW_ADDR_T_UNICAST); if (!err) __dev_set_rx_mode(dev); netif_addr_unlock_bh(dev); return err; } +EXPORT_SYMBOL(dev_vid_uc_del); + +/** + * dev_uc_del - Release secondary unicast address. + * @dev: device + * @addr: address to delete + * + * Release reference to a secondary unicast address and remove it + * from the device if the reference count drops to zero. + */ +int dev_uc_del(struct net_device *dev, const unsigned char *addr) +{ + unsigned char naddr[MAX_ADDR_LEN]; + int err; + + set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; + + err = dev_vid_uc_del(dev, addr); + return err; +} EXPORT_SYMBOL(dev_uc_del); /** @@ -642,7 +708,7 @@ int dev_uc_sync(struct net_device *to, struct net_device *from) return -EINVAL; netif_addr_lock_nested(to); - err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); + err = __hw_addr_sync(&to->uc, &from->uc, get_addr_len(to)); if (!err) __dev_set_rx_mode(to); netif_addr_unlock(to); @@ -672,7 +738,7 @@ int dev_uc_sync_multiple(struct net_device *to, struct net_device *from) return -EINVAL; netif_addr_lock_nested(to); - err = __hw_addr_sync_multiple(&to->uc, &from->uc, to->addr_len); + err = __hw_addr_sync_multiple(&to->uc, &from->uc, get_addr_len(to)); if (!err) __dev_set_rx_mode(to); netif_addr_unlock(to); @@ -696,7 +762,7 @@ void dev_uc_unsync(struct net_device *to, struct net_device *from) netif_addr_lock_bh(from); netif_addr_lock_nested(to); - __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); + __hw_addr_unsync(&to->uc, &from->uc, get_addr_len(to)); __dev_set_rx_mode(to); netif_addr_unlock(to); netif_addr_unlock_bh(from); @@ -740,18 +806,22 @@ EXPORT_SYMBOL(dev_uc_init); */ int dev_mc_add_excl(struct net_device *dev, const unsigned char *addr) { + unsigned char naddr[MAX_ADDR_LEN]; struct netdev_hw_addr *ha; - int err; + int addr_len, err; + + addr_len = set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; netif_addr_lock_bh(dev); list_for_each_entry(ha, &dev->mc.list, list) { - if (!memcmp(ha->addr, addr, dev->addr_len) && + if (!memcmp(ha->addr, addr, addr_len) && ha->type == NETDEV_HW_ADDR_T_MULTICAST) { err = -EEXIST; goto out; } } - err = __hw_addr_create_ex(&dev->mc, addr, dev->addr_len, + err = __hw_addr_create_ex(&dev->mc, addr, addr_len, NETDEV_HW_ADDR_T_MULTICAST, true, false); if (!err) __dev_set_rx_mode(dev); @@ -764,10 +834,14 @@ EXPORT_SYMBOL(dev_mc_add_excl); static int __dev_mc_add(struct net_device *dev, const unsigned char *addr, bool global) { - int err; + unsigned char naddr[MAX_ADDR_LEN]; + int addr_len, err; + + addr_len = set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; netif_addr_lock_bh(dev); - err = __hw_addr_add_ex(&dev->mc, addr, dev->addr_len, + err = __hw_addr_add_ex(&dev->mc, addr, addr_len, NETDEV_HW_ADDR_T_MULTICAST, global, false, 0); if (!err) __dev_set_rx_mode(dev); @@ -804,10 +878,14 @@ EXPORT_SYMBOL(dev_mc_add_global); static int __dev_mc_del(struct net_device *dev, const unsigned char *addr, bool global) { - int err; + unsigned char naddr[MAX_ADDR_LEN]; + int addr_len, err; + + addr_len = set_vid_addr(dev, addr, naddr); + addr = dev->vid_len ? naddr : addr; netif_addr_lock_bh(dev); - err = __hw_addr_del_ex(&dev->mc, addr, dev->addr_len, + err = __hw_addr_del_ex(&dev->mc, addr, addr_len, NETDEV_HW_ADDR_T_MULTICAST, global, false); if (!err) __dev_set_rx_mode(dev); @@ -863,7 +941,7 @@ int dev_mc_sync(struct net_device *to, struct net_device *from) return -EINVAL; netif_addr_lock_nested(to); - err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); + err = __hw_addr_sync(&to->mc, &from->mc, get_addr_len(to)); if (!err) __dev_set_rx_mode(to); netif_addr_unlock(to); @@ -893,7 +971,7 @@ int dev_mc_sync_multiple(struct net_device *to, struct net_device *from) return -EINVAL; netif_addr_lock_nested(to); - err = __hw_addr_sync_multiple(&to->mc, &from->mc, to->addr_len); + err = __hw_addr_sync_multiple(&to->mc, &from->mc, get_addr_len(to)); if (!err) __dev_set_rx_mode(to); netif_addr_unlock(to); @@ -917,7 +995,7 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) netif_addr_lock_bh(from); netif_addr_lock_nested(to); - __hw_addr_unsync(&to->mc, &from->mc, to->addr_len); + __hw_addr_unsync(&to->mc, &from->mc, get_addr_len(to)); __dev_set_rx_mode(to); netif_addr_unlock(to); netif_addr_unlock_bh(from); From patchwork Tue Feb 26 18:45:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 159239 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp3545468jad; Tue, 26 Feb 2019 10:47:01 -0800 (PST) X-Google-Smtp-Source: AHgI3IaVEdnrBx4mzi4+UBA3hXmdfkfYgtce+M1Hftjjhd3aXuunpvHC6i3q/xiZ+uXm2Et2bfUW X-Received: by 2002:a65:64d5:: with SMTP id t21mr4196032pgv.266.1551206821551; Tue, 26 Feb 2019 10:47:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551206821; cv=none; d=google.com; s=arc-20160816; b=GYcsC1/hjzSvDRNX4IfVjDo/3vZLyZbife2mLpSJR4/d1kYzM6pF2BrYVFA2Q0x/Uq CphWHx0at7369rZDFZft6kJX4UW1DmMgvMboKqaFDji4vzm9Vm+ZeJ96PYnKVHvJXNU8 UkqUh7OojB9IhbvWzpaDtRwgsVRSEx4fiAhyiYc0+NjzB50cpuj0ZxI1qMIzTpvke40u TE8BNEf0rU+CHDoaav6p4nDEKrf4VslfVOIoxufFwSlyVq+dYU9nWwYu//9+JrXY6+Vp foV3iDoaWuu7MWP/iVPcmBLaI64qW2q6RK5wf8WnK8NyCLe7OPLlM71fcRJSNKRAocxt y3FQ== 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=d3cbNscAmta6sWyhidSJIEH4Xvw9ViTv0Lvbf9jCIz4=; b=zCq+1T3bxI2UT9B5lV8fG5arHqXYB0ZugJbSwHQ6V+ds24v2L9tX9mh2EXxR1HPIwe BQhMk8pHlTX8tbwVJznfdHc0m+UaOTPTA/eBcmFmy/PQzkwbXklql5+WPCtPX1AfrNXq zhdcfGDF9w9n68jWRgtwVmqglHgujKokTu4sNsqCPMXFXyKZPGdkmTG02JhPHqBDuwHI ELd2aattq66GSUugS+ca253fpyzj5H5jEjqtptDqaAI34pCiXJ9rlmRL3ZayMztwHEEp 4+t4N+v2ebIez4gmaNnU1X2wDH72JaJvGaaftwRu3C/qqyTadByTwYKibJff5l4Quuf1 LqNA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CIH2QmCC; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p12si12723377pls.111.2019.02.26.10.47.01; Tue, 26 Feb 2019 10:47:01 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=CIH2QmCC; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729239AbfBZSqg (ORCPT + 31 others); Tue, 26 Feb 2019 13:46:36 -0500 Received: from mail-lj1-f196.google.com ([209.85.208.196]:43489 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729170AbfBZSqc (ORCPT ); Tue, 26 Feb 2019 13:46:32 -0500 Received: by mail-lj1-f196.google.com with SMTP id z20so11692717ljj.10 for ; Tue, 26 Feb 2019 10:46:31 -0800 (PST) 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=d3cbNscAmta6sWyhidSJIEH4Xvw9ViTv0Lvbf9jCIz4=; b=CIH2QmCCZCCs32qNTeyozptPDcP9BRXpEMVOjiLuUu3k8YFfSlZYZvS3DjcZCiF6PU VLBikrm6rnmhVevf1eqgvGfW5LIN3D2PfbRPKwZeNdgGu25YUA4JI3Gst2lzwvEnhhvp Mn9qYARtk1C3EAJncK9anGk2BO421bRs46Q2kCWvffs5U6VrAZ54VuiZY4JGPD4rUv0I 4Ccc/2tSOjtjoMTmki9siTm/Ohtpf/xbLzfJYCbALe61AC8vvyvU1eEEbrzNaz4tFwXl Rz9LMYbNIykuJFCCKDRr3miheT8c5m+qqprnnrgIiXpYvhBTC0L4oF8FVW7nFQIC0s2u ausg== 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=d3cbNscAmta6sWyhidSJIEH4Xvw9ViTv0Lvbf9jCIz4=; b=BSnkcccufTtGCKYK7rMN6q+uoh/q0c1W2gVROdKQkQwjirGEYG9zvWF5PVRBRzhubh 0IaMfYNRolSc2F0w1w0zHopMkZDUoVp+dVK/y6eTCezh/WchE1cHuVyL3MBA7CnARWQF DJJg3E3anECFLLjE0pj0f+MqdFDyhBuhhZMGiLLAGOT6m8C1XebeKxoJ92B4yCZrjGyF SWieJWdgwlucJySm1wOJbl5VPwBAJqBPubJ6S4zVm7a9ovrkxAZAjqXWg6ZkY3PAR1TU AWj9COII9fhvgxoG9v5TiTowR1sCvwebOd5duc0YNP2cgfMCOMLEkPx0duF80N48QyQj 6aQA== X-Gm-Message-State: AHQUAuYgNYqj8JWoS0vYEU3CGvj0AYqx9i3afAKqmCceGWkLHyBsi7YD Z0I6OCnoG2ldwLRS6ox5EYLTWA== X-Received: by 2002:a2e:8949:: with SMTP id b9mr14427888ljk.173.1551206790534; Tue, 26 Feb 2019 10:46:30 -0800 (PST) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id s129sm3015190lja.49.2019.02.26.10.46.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Feb 2019 10:46:30 -0800 (PST) From: Ivan Khoronzhuk To: davem@davemloft.net, grygorii.strashko@ti.com, f.fainelli@gmail.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jiri@mellanox.com, ilias.apalodimas@linaro.org, Ivan Khoronzhuk Subject: [PATCH net-next 2/6] net: 8021q: vlan_dev: add vid tag to addresses of uc and mc lists Date: Tue, 26 Feb 2019 20:45:52 +0200 Message-Id: <20190226184556.16082-3-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190226184556.16082-1-ivan.khoronzhuk@linaro.org> References: <20190226184556.16082-1-ivan.khoronzhuk@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Update vlan mc and uc addresses with VID tag while propagating addresses to lower devices, do this only if address is not synced. It allows at end driver level to distinguish addresses belonging to vlan devices. Signed-off-by: Ivan Khoronzhuk --- include/linux/if_vlan.h | 1 + net/8021q/vlan.h | 2 ++ net/8021q/vlan_core.c | 13 +++++++++++++ net/8021q/vlan_dev.c | 26 ++++++++++++++++++++++++++ 4 files changed, 42 insertions(+) -- 2.17.1 diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 4cca4da7a6de..94657f3c483a 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -136,6 +136,7 @@ extern struct net_device *__vlan_find_dev_deep_rcu(struct net_device *real_dev, extern int vlan_for_each(struct net_device *dev, int (*action)(struct net_device *dev, int vid, void *arg), void *arg); +extern u16 vlan_dev_get_addr_vid(struct net_device *dev, const u8 *addr); extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern __be16 vlan_dev_vlan_proto(const struct net_device *dev); diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index c46daf09a501..f083c43c508f 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -6,6 +6,8 @@ #include #include +#define NET_8021Q_VID_TSIZE 2 + /* if this changes, algorithm will have to be reworked because this * depends on completely exhausting the VLAN identifier space. Thus * it gives constant time look-up, but in many cases it wastes memory. diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index a313165e7a67..fe2ac64c13f8 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -454,6 +454,19 @@ bool vlan_uses_dev(const struct net_device *dev) } EXPORT_SYMBOL(vlan_uses_dev); +u16 vlan_dev_get_addr_vid(struct net_device *dev, const u8 *addr) +{ + u16 vid = 0; + + if (dev->vid_len != NET_8021Q_VID_TSIZE) + return vid; + + vid = addr[dev->addr_len]; + vid |= (addr[dev->addr_len + 1] & 0xf) << 8; + return vid; +} +EXPORT_SYMBOL(vlan_dev_get_addr_vid); + static struct sk_buff *vlan_gro_receive(struct list_head *head, struct sk_buff *skb) { diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 15293c2a5dd8..93d20b1f4916 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -249,6 +249,14 @@ void vlan_dev_get_realdev_name(const struct net_device *dev, char *result) strncpy(result, vlan_dev_priv(dev)->real_dev->name, 23); } +static void vlan_dev_set_addr_vid(struct net_device *vlan_dev, u8 *addr) +{ + u16 vid = vlan_dev_vlan_id(vlan_dev); + + addr[vlan_dev->addr_len] = vid & 0xff; + addr[vlan_dev->addr_len + 1] = (vid >> 8) & 0xf; +} + bool vlan_dev_inherit_address(struct net_device *dev, struct net_device *real_dev) { @@ -480,8 +488,26 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change) } } +static void vlan_dev_align_addr_vid(struct net_device *vlan_dev) +{ + struct net_device *real_dev = vlan_dev_real_dev(vlan_dev); + struct netdev_hw_addr *ha; + + if (!real_dev->vid_len) + return; + + netdev_for_each_mc_addr(ha, vlan_dev) + if (!ha->sync_cnt) + vlan_dev_set_addr_vid(vlan_dev, ha->addr); + + netdev_for_each_uc_addr(ha, vlan_dev) + if (!ha->sync_cnt) + vlan_dev_set_addr_vid(vlan_dev, ha->addr); +} + static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) { + vlan_dev_align_addr_vid(vlan_dev); dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); } From patchwork Tue Feb 26 18:45:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 159236 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp3545170jad; Tue, 26 Feb 2019 10:46:40 -0800 (PST) X-Google-Smtp-Source: AHgI3Iaj1ZIDKhd2KcLQEiUiV2I3zOXiHqGYNkMaVjskktXNNKnqjIyn/jNDPIAgTjbZFrlStnFI X-Received: by 2002:a62:5444:: with SMTP id i65mr28046348pfb.193.1551206800332; Tue, 26 Feb 2019 10:46:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551206800; cv=none; d=google.com; s=arc-20160816; b=M3i9fiETJaQXn6J75AAW6Lxm8iqqkUoWzDLLBX8E9kxKmDxG13ihXEr/fJt1F2sGUg yk7nKkVarNsl/TJ/QHDPfl3TAyzVtWDWk269Ev7gD7eBxJJ8QrJdbWOfeDKsPFEy2xsb c6MAbiilvv4RgnvMJJP84SM4bUW2568NCD+5T1I3OdAL89EXj0aEO+WLitl4Hu4cubVD QkT2BTSb4fvOnuNuktydEzqZKox1QNYm3dengvJU8WilISILL+Bl0SoZboMACJP4IYUV +52jeDwMftnk5jWhjsMvaKr6vznU1VUpE6L2ei0DglcNhFTfosOzevuYWACkY/9I0c9H 9eHw== 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=qB7J+KCADCQzZLQm80I7bfN1GrVDWJdsN+dYvepcy/4=; b=B9zqDRXmU+Ua7kMjqWmoSjvzN0Aag5rFAdwBgq/ChySbo1Cys5STuyy70SiK28dI3R TH2a/GbJAkDJvx3Ol5EgKV408JAnSJ9Q8Fs6CekFKTgZdbn3R9Do9SgbYm9vi28uk5lM 2prTUC49sG5Ks8oFh1j6LzXm4mOUiMpu7cRsHOM3yeb2mUO/i1kP6ggSn31Ye6b5wITW HILGWcxmp0tzMggmGJr5Zl7VCrGFi1eL4rcrG1QW7B2mt0MikvbxqD9Z/jtnwZUNFKZZ ffbV3wVUKI8A4n/GApPZX/RLLmDCo5QlTDyS8ZMZvIrT55BGn2rfhoBbNfhhJCfvQTdV cvxQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JyW6Njck; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w4si968423pgr.359.2019.02.26.10.46.39; Tue, 26 Feb 2019 10:46:40 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=JyW6Njck; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729292AbfBZSqi (ORCPT + 31 others); Tue, 26 Feb 2019 13:46:38 -0500 Received: from mail-lj1-f193.google.com ([209.85.208.193]:45761 "EHLO mail-lj1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729217AbfBZSqg (ORCPT ); Tue, 26 Feb 2019 13:46:36 -0500 Received: by mail-lj1-f193.google.com with SMTP id d24so11436863ljc.12 for ; Tue, 26 Feb 2019 10:46:33 -0800 (PST) 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=qB7J+KCADCQzZLQm80I7bfN1GrVDWJdsN+dYvepcy/4=; b=JyW6NjckmfTIek2crj1TZFYSEWIWmDKBFP8RbxlN+YSoxxhE4TDRGon3l5dfEJ54lo nocr1m6QLAeTaKuCI+0mX3zlacFZ1WFTAu7aB1v0uruTvz8YsLbwHKGTKKJSe0O/17yn 5wJW31P1WyW7hhzWPdK+k2/iSpbgNhk2cyVioYnOqAg5aW3O+J74PZ8MnvEEjyP5ged8 VgD0wa5Mjf9LYrkvOd/ISQqgkv6/+snyuN2p2TARZCI9ocTpQtFh7a0uMC626EZ5NZjV EzoUY9Zj96PUDO0dz4IHjZge6uo4A28X253NiNYhsvv7eEEKqN/qGkN3a1+gXtkbzzKb WWkA== 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=qB7J+KCADCQzZLQm80I7bfN1GrVDWJdsN+dYvepcy/4=; b=hVbDhzeJuP+IVjvxbPUj82SAOQUHRg2gNgX+BgzHrrx0WRfjeOA37MwUs/veqiijoo Pvps7Ut/vL8MsPYbOg3A2pzkU+7CF2Ku/qiBAfHzp38CJD2XnM9HIu13IC7zECmyHwmd 8S7055Y3SisZCdp9h4AODtUjHd2A+239OemjmAxKMr0xkaFm/v99CeZEiqcsAaKqk0lu BB6DD2kz10kUmVonu6o0YhJ+6rdqDjmpzrxFPcEKH9XzGR4eV81qS4DJPPL7mAkwfZ9H voaYFVtl+k8k1xNrSedD1yiih0vQU8ufjEYkLDSnKcxPrAKKhDs9ytgI5oXEutqvn+jO OKsQ== X-Gm-Message-State: AHQUAuYeydcZpdxLkuiZRQ0GdVhwiwvnljxlZBq+SJqxWf8UvZbLFwim qCEc3H06oh1HI58CW58neP++Uw== X-Received: by 2002:a2e:6309:: with SMTP id x9mr13764811ljb.75.1551206792934; Tue, 26 Feb 2019 10:46:32 -0800 (PST) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id s129sm3015190lja.49.2019.02.26.10.46.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Feb 2019 10:46:32 -0800 (PST) From: Ivan Khoronzhuk To: davem@davemloft.net, grygorii.strashko@ti.com, f.fainelli@gmail.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jiri@mellanox.com, ilias.apalodimas@linaro.org, Ivan Khoronzhuk Subject: [PATCH net-next 4/6] ethernet: eth: add default vid len for all ehternet kind devices Date: Tue, 26 Feb 2019 20:45:54 +0200 Message-Id: <20190226184556.16082-5-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190226184556.16082-1-ivan.khoronzhuk@linaro.org> References: <20190226184556.16082-1-ivan.khoronzhuk@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org IVDF - individual virtual device filtering. Allows to set per vlan l2 address filters on end real network device (for unicast and for multicast) and drop redundant not expected packet income. If CONFIG_VLAN_8021Q_IVDF is enabled the following changes are applied, and only for ethernet network devices. By default every ethernet netdev needs vid len = 2 bytes to be able to hold up to 4096 vids. So set it for every eth device to be correct, except vlan devs. In order to shrink all addresses of devices above vlan, the vid_len for vlan dev = 0, as result all suckers sync their addresses to common base not taking in to account vid part (vid_len of "to" devices is important only). And only vlan device is the source of addresses with actual its vid set, propagating it to parent devices while rx_mode(). Also, don't bother those ethernet devices that at this moment are not moved to vlan addressing scheme, so while end ethernet device is created - set vid_len to 0, thus, while syncing, its address space is concatenated to one dimensional like usual, and who needs IVDF - set it to NET_8021Q_VID_TSIZE. There is another decision - is to inherit vid_len or some feature flag from end root device in order to all upper devices have vlan extended address space only if exact end real device have such capability. But I didn't, because it requires more changes and probably I'm not familiar with all places where it should be inherited, I would appreciate if someone can guid where it's applicable, then it could become a little bit more limited. Signed-off-by: Ivan Khoronzhuk --- include/linux/if_vlan.h | 1 + net/8021q/Kconfig | 12 ++++++++++++ net/8021q/vlan_core.c | 12 ++++++++++++ net/8021q/vlan_dev.c | 1 + net/ethernet/eth.c | 10 ++++++++-- 5 files changed, 34 insertions(+), 2 deletions(-) -- 2.17.1 diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 94657f3c483a..9c914b31d208 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -137,6 +137,7 @@ extern int vlan_for_each(struct net_device *dev, int (*action)(struct net_device *dev, int vid, void *arg), void *arg); extern u16 vlan_dev_get_addr_vid(struct net_device *dev, const u8 *addr); +extern void vlan_dev_ivdf_set(struct net_device *dev, int enable); extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern __be16 vlan_dev_vlan_proto(const struct net_device *dev); diff --git a/net/8021q/Kconfig b/net/8021q/Kconfig index 42320180967f..3e843045739c 100644 --- a/net/8021q/Kconfig +++ b/net/8021q/Kconfig @@ -38,3 +38,15 @@ config VLAN_8021Q_MVRP supersedes GVRP and is not backwards-compatible. If unsure, say N. + +config VLAN_8021Q_IVDF + bool "IVDF (Individual Virtual Device Filtering) support" + depends on VLAN_8021Q + help + Select this to enable IVDF addressing scheme support. IVDF is used + for automatic propagation of registered VLANs addresses to real end + devices. If no device supporting IVDF then disable this as it can + consume some memory in configuration with complex network device + structures to hold vlan addresses. + + If unsure, say N. diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index fe2ac64c13f8..310b6cd39f22 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -454,6 +454,18 @@ bool vlan_uses_dev(const struct net_device *dev) } EXPORT_SYMBOL(vlan_uses_dev); +void vlan_dev_ivdf_set(struct net_device *dev, int enable) +{ +#ifdef CONFIG_VLAN_8021Q_IVDF + if (enable) { + dev->vid_len = NET_8021Q_VID_TSIZE; + return; + } +#endif + dev->vid_len = 0; +} +EXPORT_SYMBOL(vlan_dev_ivdf_set); + u16 vlan_dev_get_addr_vid(struct net_device *dev, const u8 *addr) { u16 vid = 0; diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 634436e780f1..e4120aca4b9b 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -896,5 +896,6 @@ void vlan_setup(struct net_device *dev) dev->min_mtu = 0; dev->max_mtu = ETH_MAX_MTU; + vlan_dev_ivdf_set(dev, 0); eth_zero_addr(dev->broadcast); } diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index f7a3d7a171c7..95497cac24eb 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -381,6 +381,7 @@ void ether_setup(struct net_device *dev) dev->flags = IFF_BROADCAST|IFF_MULTICAST; dev->priv_flags |= IFF_TX_SKB_SHARING; + vlan_dev_ivdf_set(dev, 1); eth_broadcast_addr(dev->broadcast); } @@ -404,8 +405,13 @@ EXPORT_SYMBOL(ether_setup); struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, unsigned int rxqs) { - return alloc_netdev_mqs(sizeof_priv, "eth%d", NET_NAME_UNKNOWN, - ether_setup, txqs, rxqs); + struct net_device *dev; + + dev = alloc_netdev_mqs(sizeof_priv, "eth%d", NET_NAME_UNKNOWN, + ether_setup, txqs, rxqs); + + vlan_dev_ivdf_set(dev, 0); + return dev; } EXPORT_SYMBOL(alloc_etherdev_mqs); From patchwork Tue Feb 26 18:45:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 159238 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp3545312jad; Tue, 26 Feb 2019 10:46:51 -0800 (PST) X-Google-Smtp-Source: AHgI3IZQJc01sy+AFhez6KtTnOu92a+/MiKr7deJ9pDqc9Osl/Tds2USpkImII1OPfzQFgr7keiY X-Received: by 2002:a17:902:aa06:: with SMTP id be6mr27769783plb.57.1551206811496; Tue, 26 Feb 2019 10:46:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551206811; cv=none; d=google.com; s=arc-20160816; b=bkX9jV2Qd7ywlDi3wOOgfkLhJ+ihj7EoP+pPaiINetbLzH/vCsG/ZyOvhINy/UgAvc /vuzubLY03W8vPstR4XhtBopilEgVBCHYeU4e+N8EvzL58sQEmmpN6poNK2mf6dUBZ4i sezTu3oRWixoMIm7uCq613jkP2JsztVuGMdTnESoetwVZhISAK/YmHBmOegMllnMziro W8nIckkcRJ/XrpkcH0qlscj4cXsvVRmkQKEKvrwcB73LfrwHA4E/HTI8UiGzN0iPVXu/ gw+nr5OLfwe0fGDONjd52oL6r8D1aGjsfTm6SlsTprextzvLg3E6yXTeRzuFYQYr+nxD Og9Q== 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=jy1VVBUzKtjrg74/rZ/KvvMy2H0d6BKBUN8LnXHZx/8=; b=P8YYD7KBzjINCKseXOb2f+v7qwHmInBbGjEllNDK+1Kfu8vSo3k029LPHCpFKvq1up QxhPLB6opnQDf9xl+Z846vi9mNSMpi4POj41SijiO+y4lfftI4SoB/o0Eaz6tTKWTlqQ KPIs7jCyaxIl2nqOE0a+0NHjFjWM8Pnu4tkA1vfnBf+PRaZnf6R+wRo8tAdwXL+RbDaH iLBh8VholVXFRn5n7sfINcv7jf3rf+IQD9Z3TJMo4aHAbgyL/+YLHYNPzZL2YvVktq7Y 57+CLlCD8vt15HEo7nJf8mMYw7XkEYkZjgjXPMqmAL6TiWi3bCu5W832qS5wq9ibTzJF n6Yw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=a56auifa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 128si12586367pgb.373.2019.02.26.10.46.51; Tue, 26 Feb 2019 10:46:51 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=a56auifa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729272AbfBZSqi (ORCPT + 31 others); Tue, 26 Feb 2019 13:46:38 -0500 Received: from mail-lf1-f66.google.com ([209.85.167.66]:36333 "EHLO mail-lf1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729223AbfBZSqg (ORCPT ); Tue, 26 Feb 2019 13:46:36 -0500 Received: by mail-lf1-f66.google.com with SMTP id x206so2425926lff.3 for ; Tue, 26 Feb 2019 10:46:34 -0800 (PST) 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=jy1VVBUzKtjrg74/rZ/KvvMy2H0d6BKBUN8LnXHZx/8=; b=a56auifaLwutXD9YhaJZGx66ZY4jM6tYPj22JS4j6c3jOhzqRkPxDu6bT69LvMpnF6 Iw5I7EsC/Pu4U0KrW069g5UOpPpP1uK36jMoF8xDi7qhsNgrQLYh0i2dlvZyJ8EPmEcM PLzj5cQSYO+3AXtmS8ucLgyAanEwZVyRZq3evb52jk4+tQ5a57BGCvfmZTkPOJF0VuRC 54Hc18YCDlXrDCE0BcYlCegiFQqlW5R27EMNysu8psnGxFk4F7HLMcfGWdMl8oOL9Uq3 tBUQu8ZHKKNM62Fx/yjAhVHZkgher1NJ2Fx3QDJWisPihemsKVeqAX7uWye/cKjAmv5D 1PVw== 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=jy1VVBUzKtjrg74/rZ/KvvMy2H0d6BKBUN8LnXHZx/8=; b=UOk0bHrDaiqtLyBHAisBUR2wrgttq8i15z8306mtccuPXMTe87FD0D+GxElcjOoEqw J9PDqOKgEkyL7z4L7DpOiSY49ciKUGezVytdXV8iNUmSZCoNXawBu3hDC/bCu3o8jMn+ iL8M7FkjafLef+iPR8XcVM9W8srceFua80J1ftcLotuG8f2B2nt1NC1k0dxN57T1Xw5N UjBMPe3At1zonwNNugWP2wtCfxgJN3LcWRe4l+r+8kUmYsSCDNsSoF/BVLfrWVnr/csP SX8RN3cth4BhJF/1zO2fgzGP1Fef3XHoV1OwsRds75L5RwQJu6ebtmkH0t8zKBoN8Bx5 suoQ== X-Gm-Message-State: AHQUAubESiHp6HWKz0RIv6gPEafHBSwFUXaUzW9OqsYgpY5GZBny7ckd GAjzTskKhxhyCBxOQfjNJyVjbg== X-Received: by 2002:ac2:54b6:: with SMTP id w22mr5515367lfk.132.1551206794139; Tue, 26 Feb 2019 10:46:34 -0800 (PST) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id s129sm3015190lja.49.2019.02.26.10.46.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Feb 2019 10:46:33 -0800 (PST) From: Ivan Khoronzhuk To: davem@davemloft.net, grygorii.strashko@ti.com, f.fainelli@gmail.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jiri@mellanox.com, ilias.apalodimas@linaro.org, Ivan Khoronzhuk Subject: [PATCH net-next 5/6] net: ethernet: ti: cpsw: update mc filtering to use IVDF Date: Tue, 26 Feb 2019 20:45:55 +0200 Message-Id: <20190226184556.16082-6-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190226184556.16082-1-ivan.khoronzhuk@linaro.org> References: <20190226184556.16082-1-ivan.khoronzhuk@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The cpsw can filter multicast addresses only per vlan. Thus if mcast address is set for one of them or only for real device it must be added for every created vlan consuming ALE table w/o reason. In order to simplify dispatching vlan filters, the IVDF recently added is resused. In case IVDF is disabled - mc is updated only for real device as before. The previous method is harder to reuse and vlan filtering is limited only for vlans directly connected to real netdev, so drop it in flavor of IVDF decision. Signed-off-by: Ivan Khoronzhuk --- drivers/net/ethernet/ti/Kconfig | 1 + drivers/net/ethernet/ti/cpsw.c | 113 ++++---------------------------- 2 files changed, 13 insertions(+), 101 deletions(-) -- 2.17.1 diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index bb126be1eb72..c99c08ece9a1 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig @@ -65,6 +65,7 @@ config TI_CPSW select TI_DAVINCI_CPDMA select TI_DAVINCI_MDIO select TI_CPSW_PHY_SEL + select VLAN_8021Q_IVDF select TI_CPSW_ALE select MFD_SYSCON select REGMAP diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index a591583d120e..fd76d1f12911 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -693,108 +693,21 @@ static int cpsw_set_mc(struct net_device *ndev, const u8 *addr, return ret; } -static int cpsw_update_vlan_mc(struct net_device *vdev, int vid, void *ctx) +static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr) { - struct addr_sync_ctx *sync_ctx = ctx; - struct netdev_hw_addr *ha; - int found = 0, ret = 0; - - if (!vdev || !(vdev->flags & IFF_UP)) - return 0; - - /* vlan address is relevant if its 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->consumed++; - - if (sync_ctx->flush) { - if (!found) - cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 0); - return 0; - } - - 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 addr_sync_ctx sync_ctx; - int ret; - - sync_ctx.consumed = 0; - 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.consumed < num && !ret) - ret = cpsw_set_mc(ndev, addr, -1, 1); - - 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.consumed = 0; - 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.consumed == num) - cpsw_set_mc(ndev, addr, -1, 0); + u16 vid; + vid = vlan_dev_get_addr_vid(ndev, addr); + cpsw_set_mc(ndev, addr, vid ? vid : -1, 1); return 0; } -static int cpsw_purge_vlan_mc(struct net_device *vdev, int vid, void *ctx) +static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr) { - struct addr_sync_ctx *sync_ctx = ctx; - struct netdev_hw_addr *ha; - int found = 0; - - if (!vdev || !(vdev->flags & IFF_UP)) - return 0; - - /* vlan address is relevant if its 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) - return 0; - - sync_ctx->consumed++; - 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.consumed = 0; - - vlan_for_each(ndev, cpsw_purge_vlan_mc, &sync_ctx); - if (sync_ctx.consumed < num) - cpsw_set_mc(ndev, addr, -1, 0); + u16 vid; + vid = vlan_dev_get_addr_vid(ndev, addr); + cpsw_set_mc(ndev, addr, vid ? vid : -1, 0); return 0; } @@ -816,8 +729,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) cpsw_ale_set_allmulti(cpsw->ale, ndev->flags & IFF_ALLMULTI); /* 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); + __dev_mc_sync(ndev, cpsw_add_mc_addr, cpsw_del_mc_addr); } static void cpsw_intr_enable(struct cpsw_common *cpsw) @@ -1970,9 +1882,6 @@ 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; } @@ -2099,7 +2008,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"); - __hw_addr_ref_unsync_dev(&ndev->mc, ndev, cpsw_purge_all_mc); + __dev_mc_unsync(ndev, cpsw_del_mc_addr); netif_tx_stop_all_queues(priv->ndev); netif_carrier_off(priv->ndev); @@ -3435,6 +3344,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) priv_sl2->emac_port = 1; cpsw->slaves[1].ndev = ndev; ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX; + vlan_dev_ivdf_set(ndev, 1); ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops; @@ -3696,6 +3606,7 @@ static int cpsw_probe(struct platform_device *pdev) } ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX; + vlan_dev_ivdf_set(ndev, 1); ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops; From patchwork Tue Feb 26 18:45:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 159237 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp3545197jad; Tue, 26 Feb 2019 10:46:41 -0800 (PST) X-Google-Smtp-Source: AHgI3IbO1k7pX/18xz1nXKvCDwh0xGBdlCIuciZh3ZU6t0hXLRNgQ1aU4fLYcav9Tym1Gs/v0D6+ X-Received: by 2002:aa7:8d57:: with SMTP id s23mr27254107pfe.237.1551206801674; Tue, 26 Feb 2019 10:46:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551206801; cv=none; d=google.com; s=arc-20160816; b=lMX3Q1+ovpq7S0YCdhW7QCG7K7CZQylHvnxVppUSulS5xna0vPzSXu+B+TfTB8NJI6 Imspj3GTpzMjy67f6C9gFNSOBdD4JLhOzTw9TlQI/SSFHWpTtwdY8YPzJdGYnmToiGD3 dxOxCbgyO3+lCR2NiSJL9GpTBxIK+oRLt6+fZC8V9zYGrXkpKles4rNQzRVtjzoNM5Uh 8PGVeGg8JQdFZkiqUBKa3M9VTqulMZwJW0JuxlVb6PflHZozXbI9Sm95pev9YF3NJap6 M+xComjKfQzIzZqmR8MG/dsRJQSC5+j4F7/85zFD0a3pozlrt082rwss1ItT8u4fj3LO 5vsg== 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=Q2OKdZERs/8jAWziFkYs/uIS+0wWtSfv5QZ7vRzwEFY=; b=TnhjU5Zy+7WD8rET98P2FMKJEKH6snSij5jG009myz+hH6cJacOZWaAQdNFYK1LkDc wHkgwKJ3BW/XwXct1p++UpydaemzbsTgRqX4uNGfS4+yumBqZJoo7S65Kj9HHe+EQuJN saDiXddBRGX4+boWuYJE9A6ep/vQAfubMxCzih35P1nG3wExAqNDe5I/rdcj4pNm9u58 H/izLiuQHrXM2uS5uRzm/4PToMNq2Z6xOw0kFS6x4GN/JKEaaZlf6lROxLRVgbovTrSz +BZ54oemimBPL/v7uSk+HHbR3Wr1FVcMyzO1wUJwNTQkZY9v3uwZNpUGgdMORG58tvoG FviQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DU5Crjvh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 128si12586367pgb.373.2019.02.26.10.46.41; Tue, 26 Feb 2019 10:46:41 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=DU5Crjvh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729318AbfBZSqj (ORCPT + 31 others); Tue, 26 Feb 2019 13:46:39 -0500 Received: from mail-lj1-f195.google.com ([209.85.208.195]:35740 "EHLO mail-lj1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729236AbfBZSqi (ORCPT ); Tue, 26 Feb 2019 13:46:38 -0500 Received: by mail-lj1-f195.google.com with SMTP id t13so7349880lji.2 for ; Tue, 26 Feb 2019 10:46:36 -0800 (PST) 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=Q2OKdZERs/8jAWziFkYs/uIS+0wWtSfv5QZ7vRzwEFY=; b=DU5Crjvhw0VaZz+4UB44EKVB2DkEtQ03+SJ3M9IdzqteTvgTrTJoSqMxx9OKPvdaaP c+d2HHMpV47MLBrXSfcGo64o3/xCPa3+eqtvh9zSycDFLj0OdNjxcTZ7kGiQ6r1Fk4GB 74iAtrXQapvmFfK3QufjAUNplX2GrXG0TZCFvY6VRq+G8dnw1hpq3vusiweiD1XpSik/ EDl2orgZ33DPMghWxsqguLGIvNzNcoG00TRskHYX8mRqV+E32vRccLdsGcA65cF/zqmz zv/mWiXGhG1H8A7zyi5u9bbKs/V0FAVi2vK8OgQgK8XmY779SeINYGejHOdAb76w4/NM mmPA== 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=Q2OKdZERs/8jAWziFkYs/uIS+0wWtSfv5QZ7vRzwEFY=; b=X1IN0gxlPG2iKCEUlgdH8Apd94TdYwqBEXxcXxyJ0EF8gx3OWdZBBu7IrkLUzUhq32 nYX2Bfm3d16osQ8LEYumr1hjCi7LKCJ0IL4HL1krf1liP0ZIGIKaL9rRZJfiDDQ7t5r0 AQe4gLuIMG3B2bhCRHLx2zEleGe7SbWnkYha9fJVE8ZIXtUqvvIZr6DFK5qBe1LmQ3K5 3hJdgKh+L4Y2WGEli639zJH4MsOig7nNV4Fl+r7FYpiedgB2vAcmyCfO26cesvRWZJpv IBE+oNKKxgxXBogHZYVIvbrWQG+0aAK+O+0bngT0Uhb7bPtoBIo++/KsKvfoM9S3ZiDL FHgw== X-Gm-Message-State: AHQUAuYNoL4o3mdNPSfHwtG5yUOpGxcUsrzmNgOqOOm5eRG45aI8QXx0 CAPAm7M4i9j6jWGOk94ODnrQtw== X-Received: by 2002:a2e:88d1:: with SMTP id a17mr14200214ljk.169.1551206795225; Tue, 26 Feb 2019 10:46:35 -0800 (PST) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id s129sm3015190lja.49.2019.02.26.10.46.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Feb 2019 10:46:34 -0800 (PST) From: Ivan Khoronzhuk To: davem@davemloft.net, grygorii.strashko@ti.com, f.fainelli@gmail.com Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, jiri@mellanox.com, ilias.apalodimas@linaro.org, Ivan Khoronzhuk Subject: [PATCH net-next 6/6] net: ethernet: ti: cpsw: add macvlan and ucast/vlan filtering support Date: Tue, 26 Feb 2019 20:45:56 +0200 Message-Id: <20190226184556.16082-7-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190226184556.16082-1-ivan.khoronzhuk@linaro.org> References: <20190226184556.16082-1-ivan.khoronzhuk@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The cpsw supports unicast filtering as for real as for vlan devices now, but has no flag set for that. As result, once macvlan or vlan adds new ucast address the cpsw is silently toggled to promiscuous mode. That's smth not expected, so patch fixes it. A unicast address for vlan has to be presented by vlan/unicast entry in ALE table. At this moment, while vlan address change, entry is not created in any form, even just like real device unicast used for macvlan, leaving only address inherited from real device created while vlan addition. Therefore, program unicast entries for vlans by using IVDF, it allows to add only vlan/unicast entries for vlans, omitting real device ucast entries unless they are added for macvans or so, as they are redundant for vlans and just consume forwarding table and in case of matching packet income - CPU time. So, after this patch, cpsw has ability to handle macvlan and vlan ucasts, synchronizing ucast tables for these devices with cpsw ALE table exclusively. Signed-off-by: Ivan Khoronzhuk --- drivers/net/ethernet/ti/cpsw.c | 62 ++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 6 deletions(-) -- 2.17.1 diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index fd76d1f12911..c6d5ddc05299 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -693,6 +693,31 @@ static int cpsw_set_mc(struct net_device *ndev, const u8 *addr, return ret; } +static int cpsw_set_uc(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 flags, port, ret; + + if (vid < 0) { + if (cpsw->data.dual_emac) + vid = cpsw->slaves[priv->emac_port].port_vlan; + else + vid = 0; + } + + port = HOST_PORT_NUM; + flags = vid ? ALE_VLAN : 0; + + if (add) + ret = cpsw_ale_add_ucast(cpsw->ale, addr, port, flags, vid); + else + ret = cpsw_ale_del_ucast(cpsw->ale, addr, port, flags, vid); + + return ret; +} + static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr) { u16 vid; @@ -711,6 +736,24 @@ static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr) return 0; } +static int cpsw_add_uc_addr(struct net_device *ndev, const u8 *addr) +{ + u16 vid; + + vid = vlan_dev_get_addr_vid(ndev, addr); + cpsw_set_uc(ndev, addr, vid ? vid : -1, 1); + return 0; +} + +static int cpsw_del_uc_addr(struct net_device *ndev, const u8 *addr) +{ + u16 vid; + + vid = vlan_dev_get_addr_vid(ndev, addr); + cpsw_set_uc(ndev, addr, vid ? vid : -1, 0); + return 0; +} + static void cpsw_ndo_set_rx_mode(struct net_device *ndev) { struct cpsw_common *cpsw = ndev_to_cpsw(ndev); @@ -730,6 +773,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) /* add/remove mcast address either for real netdev or for vlan */ __dev_mc_sync(ndev, cpsw_add_mc_addr, cpsw_del_mc_addr); + __dev_uc_sync(ndev, cpsw_add_uc_addr, cpsw_del_uc_addr); } static void cpsw_intr_enable(struct cpsw_common *cpsw) @@ -2009,6 +2053,7 @@ static int cpsw_ndo_stop(struct net_device *ndev) cpsw_info(priv, ifdown, "shutting down cpsw device\n"); __dev_mc_unsync(ndev, cpsw_del_mc_addr); + __dev_uc_unsync(ndev, cpsw_del_uc_addr); netif_tx_stop_all_queues(priv->ndev); netif_carrier_off(priv->ndev); @@ -2369,10 +2414,12 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, if (ret != 0) return ret; - ret = cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, - HOST_PORT_NUM, ALE_VLAN, vid); - if (ret != 0) - goto clean_vid; + if (!priv->ndev->vid_len) { + ret = cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, + HOST_PORT_NUM, ALE_VLAN, vid); + if (ret != 0) + goto clean_vid; + } ret = cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast, mcast_mask, ALE_VLAN, vid, 0); @@ -2381,8 +2428,9 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, return 0; clean_vlan_ucast: - cpsw_ale_del_ucast(cpsw->ale, priv->mac_addr, - HOST_PORT_NUM, ALE_VLAN, vid); + if (!priv->ndev->vid_len) + cpsw_ale_del_ucast(cpsw->ale, priv->mac_addr, + HOST_PORT_NUM, ALE_VLAN, vid); clean_vid: cpsw_ale_del_vlan(cpsw->ale, vid, 0); return ret; @@ -3344,6 +3392,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) priv_sl2->emac_port = 1; cpsw->slaves[1].ndev = ndev; ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX; + ndev->priv_flags |= IFF_UNICAST_FLT; vlan_dev_ivdf_set(ndev, 1); ndev->netdev_ops = &cpsw_netdev_ops; @@ -3606,6 +3655,7 @@ static int cpsw_probe(struct platform_device *pdev) } ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX; + ndev->priv_flags |= IFF_UNICAST_FLT; vlan_dev_ivdf_set(ndev, 1); ndev->netdev_ops = &cpsw_netdev_ops;