* RESPONSE
From: Ms. Ella Golan @ 2018-04-30 13:44 UTC (permalink / raw)
To: Recipients
I am Ms.Ella Golan, I am the Executive Vice President Banking Division with FIRST INTERNATIONAL BANK OF ISRAEL LTD (FIBI). I am getting in touch with you regarding an extremely important and urgent matter. If you would oblige me the opportunity, I shall provide you with details upon your response.
Faithfully,
Ms.Ella Golan
^ permalink raw reply
* Re: [RFC PATCH 4/5] net: macb: Add support for suspend/resume with full power down
From: Claudiu Beznea @ 2018-05-03 12:23 UTC (permalink / raw)
To: Harini Katakam
Cc: Nicolas Ferre, David Miller, netdev, linux-kernel, michals,
appanad
In-Reply-To: <CAFcVECK3UO+tckXnTKvLpWe3+RiZ7fyDmS+3JjgOdeQTRwy_FQ@mail.gmail.com>
On 03.05.2018 14:20, Harini Katakam wrote:
> Hi Claudiu,
>
> On Thu, May 3, 2018 at 3:39 PM, Claudiu Beznea
> <Claudiu.Beznea@microchip.com> wrote:
>>
>>
>> On 22.03.2018 15:51, harinikatakamlinux@gmail.com wrote:
>>> From: Harini Katakam <harinik@xilinx.com>
>>>
>>> When macb device is suspended and system is powered down, the clocks
>>> are removed and hence macb should be closed gracefully and restored
>>> upon resume.
>>
>> Is this a power saving mode which shut down the core?
>
> The Ethernet IP is suspended and a majority of the SoC is shut down, yes.
>
> <snip>
>>> + netif_device_detach(netdev);
>>> + } else {
>>> + netif_device_detach(netdev);
>>> + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
>>> + napi_disable(&queue->napi);
>>> + phy_stop(netdev->phydev);
>>> + phy_suspend(netdev->phydev);
>>> + spin_lock_irqsave(&bp->lock, flags);
>>> + macb_reset_hw(bp);
>>> + spin_unlock_irqrestore(&bp->lock, flags);
>>
>> Wouldn't be simple to just call macb_close() here?
>
> <snip>
>>
>> Wouln't be simpler to call macb_open() here?
>
> No, I think that would be excessive for suspend. This does just
> enough to put the IP into suspend and cut off clocks.
> For ex., the RX and TX buffers are not freed and allocated again
> in this cycle, just the buffer descriptors.
>
For me looks simpler to just call macb_close()/macb_open() in suspend/resume
hooks. Maybe this doesn't fit to your needs... But most of the code you
added in suspend/resume hooks is already present in macb_open()/macb_close(),
except the TX/RX buffers alloc/free.
SAMA5D2 also uses this IP. SAMA5d2 has a power saving mode where core power is cut
off (including this IP). We are using macb_open()/macb_close() + restoring all
few other registers after this (by calling macb_set_rx_mode() and a variant of
macb_set_features() and few other registers). This is not yet mainlined. I was
intending to send soon a version.
Thank you,
Claudiu
> Regards,
> Harini
>
^ permalink raw reply
* Hi,I couldn't reach you
From: Lisa Jaster @ 2018-05-03 12:29 UTC (permalink / raw)
Hi,
I have some important message for you
^ permalink raw reply
* Re: [PATCH net-next] inet: add bound ports statistic
From: kbuild test robot @ 2018-05-03 12:37 UTC (permalink / raw)
To: Stephen Hemminger
Cc: kbuild-all, netdev, Stephen Hemminger, Stephen Hemminger
In-Reply-To: <20180502221108.3261-1-sthemmin@microsoft.com>
[-- Attachment #1: Type: text/plain, Size: 1487 bytes --]
Hi Stephen,
I love your patch! Yet something to improve:
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Stephen-Hemminger/inet-add-bound-ports-statistic/20180503-182729
config: i386-randconfig-x000-201817 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
>> net/ipv4/inet_hashtables.c:62:14: error: conflicting types for 'inet_bind_bucket_count'
unsigned int inet_bind_bucket_count(struct proto *prot)
^~~~~~~~~~~~~~~~~~~~~~
In file included from net/ipv4/inet_hashtables.c:26:0:
include/net/inet_hashtables.h:199:5: note: previous declaration of 'inet_bind_bucket_count' was here
int inet_bind_bucket_count(struct proto *prot);
^~~~~~~~~~~~~~~~~~~~~~
vim +/inet_bind_bucket_count +62 net/ipv4/inet_hashtables.c
60
61 /* Count how many any entries are in the bind hash table */
> 62 unsigned int inet_bind_bucket_count(struct proto *prot)
63 {
64 struct inet_hashinfo *hinfo = prot->h.hashinfo;
65 unsigned int i, ports = 0;
66
67 for (i = 0; i < hinfo->bhash_size; i++)
68 ports += hinfo->bhash[i].count;
69
70 return ports;
71 }
72
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30789 bytes --]
^ permalink raw reply
* [PATCH net-next mlxsw v2 0/2] bridge: FDB: Notify about removal of non-user-added entries
From: Petr Machata @ 2018-05-03 12:43 UTC (permalink / raw)
To: netdev, bridge
Cc: ivecera, f.fainelli, andrew, vivien.didelot, idosch, jiri, davem
Device drivers may generally need to keep in sync with bridge's FDB. In
particular, for its offload of tc mirror action where the mirrored-to
device is a gretap device, mlxsw needs to listen to a number of events,
FDB events among the others. SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE would be
a natural notification in that case.
However, for removal of FDB entries added due to device activity (as
opposed to explicit addition through "bridge fdb add" or similar), there
are no notifications.
Thus in patch #1, add the "added_by_user" field to switchdev
notifications sent for FDB activity. Adapt drivers to ignore activity on
non-user-added entries, to maintain the current behavior. Specifically
in case of mlxsw, allow mlxsw_sp_span_respin() call for any and all FDB
updates.
In patch #2, change the bridge driver to actually emit notifications for
these FDB entries. Take care not to send notification for bridge
updates that itself originate in SWITCHDEV_FDB_*_TO_BRIDGE events.
Changes from v1 to v2:
- Instead of introducing a new variant of fdb_delete(), add a new
parameter to the existing function.
- Name the parameter swdev_notify, not notify.
Petr Machata (2):
switchdev: Add fdb.added_by_user to switchdev notifications
net: bridge: Notify about !added_by_user FDB entries
.../ethernet/mellanox/mlxsw/spectrum_switchdev.c | 4 ++
drivers/net/ethernet/rocker/rocker_main.c | 2 +
include/net/switchdev.h | 1 +
net/bridge/br.c | 4 +-
net/bridge/br_fdb.c | 47 ++++++++++++----------
net/bridge/br_private.h | 6 ++-
net/bridge/br_switchdev.c | 12 ++++--
net/dsa/slave.c | 5 ++-
8 files changed, 51 insertions(+), 30 deletions(-)
--
2.4.11
^ permalink raw reply
* [PATCH net-next mlxsw v2 1/2] switchdev: Add fdb.added_by_user to switchdev notifications
From: Petr Machata @ 2018-05-03 12:43 UTC (permalink / raw)
To: netdev, bridge
Cc: ivecera, f.fainelli, andrew, vivien.didelot, idosch, jiri, davem
In-Reply-To: <cover.1525350809.git.petrm@mellanox.com>
The following patch enables sending notifications also for events on FDB
entries that weren't added by the user. Give the drivers the information
necessary to distinguish between the two origins of FDB entries.
To maintain the current behavior, have switchdev-implementing drivers
bail out on notifications about non-user-added FDB entries. In case of
mlxsw driver, allow a call to mlxsw_sp_span_respin() so that SPAN over
bridge catches up with the changed FDB.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 4 ++++
drivers/net/ethernet/rocker/rocker_main.c | 2 ++
include/net/switchdev.h | 1 +
net/bridge/br_switchdev.c | 10 +++++++---
net/dsa/slave.c | 5 ++++-
5 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 1af99fe..3973d90 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -2270,6 +2270,8 @@ static void mlxsw_sp_switchdev_event_work(struct work_struct *work)
switch (switchdev_work->event) {
case SWITCHDEV_FDB_ADD_TO_DEVICE:
fdb_info = &switchdev_work->fdb_info;
+ if (!fdb_info->added_by_user)
+ break;
err = mlxsw_sp_port_fdb_set(mlxsw_sp_port, fdb_info, true);
if (err)
break;
@@ -2279,6 +2281,8 @@ static void mlxsw_sp_switchdev_event_work(struct work_struct *work)
break;
case SWITCHDEV_FDB_DEL_TO_DEVICE:
fdb_info = &switchdev_work->fdb_info;
+ if (!fdb_info->added_by_user)
+ break;
mlxsw_sp_port_fdb_set(mlxsw_sp_port, fdb_info, false);
break;
case SWITCHDEV_FDB_ADD_TO_BRIDGE: /* fall through */
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index 056cb60..152d694 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2783,6 +2783,8 @@ static int rocker_switchdev_event(struct notifier_block *unused,
switch (event) {
case SWITCHDEV_FDB_ADD_TO_DEVICE: /* fall through */
case SWITCHDEV_FDB_DEL_TO_DEVICE:
+ if (!fdb_info->added_by_user)
+ break;
memcpy(&switchdev_work->fdb_info, ptr,
sizeof(switchdev_work->fdb_info));
switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 39bc855..d574ce6 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -155,6 +155,7 @@ struct switchdev_notifier_fdb_info {
struct switchdev_notifier_info info; /* must be first */
const unsigned char *addr;
u16 vid;
+ bool added_by_user;
};
static inline struct net_device *
diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
index ee775f4..71a03c4 100644
--- a/net/bridge/br_switchdev.c
+++ b/net/bridge/br_switchdev.c
@@ -102,13 +102,15 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
static void
br_switchdev_fdb_call_notifiers(bool adding, const unsigned char *mac,
- u16 vid, struct net_device *dev)
+ u16 vid, struct net_device *dev,
+ bool added_by_user)
{
struct switchdev_notifier_fdb_info info;
unsigned long notifier_type;
info.addr = mac;
info.vid = vid;
+ info.added_by_user = added_by_user;
notifier_type = adding ? SWITCHDEV_FDB_ADD_TO_DEVICE : SWITCHDEV_FDB_DEL_TO_DEVICE;
call_switchdev_notifiers(notifier_type, dev, &info.info);
}
@@ -123,12 +125,14 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
case RTM_DELNEIGH:
br_switchdev_fdb_call_notifiers(false, fdb->key.addr.addr,
fdb->key.vlan_id,
- fdb->dst->dev);
+ fdb->dst->dev,
+ fdb->added_by_user);
break;
case RTM_NEWNEIGH:
br_switchdev_fdb_call_notifiers(true, fdb->key.addr.addr,
fdb->key.vlan_id,
- fdb->dst->dev);
+ fdb->dst->dev,
+ fdb->added_by_user);
break;
}
}
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index f3fb3a0..c287f1e 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1441,6 +1441,7 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+ struct switchdev_notifier_fdb_info *fdb_info = ptr;
struct dsa_switchdev_event_work *switchdev_work;
if (!dsa_slave_dev_check(dev))
@@ -1458,8 +1459,10 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
switch (event) {
case SWITCHDEV_FDB_ADD_TO_DEVICE: /* fall through */
case SWITCHDEV_FDB_DEL_TO_DEVICE:
+ if (!fdb_info->added_by_user)
+ break;
if (dsa_slave_switchdev_fdb_work_init(switchdev_work,
- ptr))
+ fdb_info))
goto err_fdb_work_init;
dev_hold(dev);
break;
--
2.4.11
^ permalink raw reply related
* [PATCH net-next mlxsw v2 2/2] net: bridge: Notify about !added_by_user FDB entries
From: Petr Machata @ 2018-05-03 12:43 UTC (permalink / raw)
To: netdev, bridge
Cc: jiri, idosch, ivecera, davem, stephen, andrew, vivien.didelot,
f.fainelli
In-Reply-To: <cover.1525350809.git.petrm@mellanox.com>
Do not automatically bail out on sending notifications about activity on
non-user-added FDB entries. Instead, notify about this activity except
for cases where the activity itself originates in a notification, to
avoid sending duplicate notifications.
Signed-off-by: Petr Machata <petrm@mellanox.com>
---
net/bridge/br.c | 4 ++--
net/bridge/br_fdb.c | 47 ++++++++++++++++++++++++++---------------------
net/bridge/br_private.h | 6 ++++--
net/bridge/br_switchdev.c | 2 +-
4 files changed, 33 insertions(+), 26 deletions(-)
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 671d13c..c6b033e 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -141,7 +141,7 @@ static int br_switchdev_event(struct notifier_block *unused,
case SWITCHDEV_FDB_ADD_TO_BRIDGE:
fdb_info = ptr;
err = br_fdb_external_learn_add(br, p, fdb_info->addr,
- fdb_info->vid);
+ fdb_info->vid, false);
if (err) {
err = notifier_from_errno(err);
break;
@@ -152,7 +152,7 @@ static int br_switchdev_event(struct notifier_block *unused,
case SWITCHDEV_FDB_DEL_TO_BRIDGE:
fdb_info = ptr;
err = br_fdb_external_learn_del(br, p, fdb_info->addr,
- fdb_info->vid);
+ fdb_info->vid, false);
if (err)
err = notifier_from_errno(err);
break;
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index a1c409c..b19e310 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -40,7 +40,7 @@ static struct kmem_cache *br_fdb_cache __read_mostly;
static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
const unsigned char *addr, u16 vid);
static void fdb_notify(struct net_bridge *br,
- const struct net_bridge_fdb_entry *, int);
+ const struct net_bridge_fdb_entry *, int, bool);
int __init br_fdb_init(void)
{
@@ -195,7 +195,8 @@ static void fdb_del_hw_addr(struct net_bridge *br, const unsigned char *addr)
}
}
-static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f)
+static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f,
+ bool swdev_notify)
{
trace_fdb_delete(br, f);
@@ -205,7 +206,7 @@ static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f)
hlist_del_init_rcu(&f->fdb_node);
rhashtable_remove_fast(&br->fdb_hash_tbl, &f->rhnode,
br_fdb_rht_params);
- fdb_notify(br, f, RTM_DELNEIGH);
+ fdb_notify(br, f, RTM_DELNEIGH, swdev_notify);
call_rcu(&f->rcu, fdb_rcu_free);
}
@@ -241,7 +242,7 @@ static void fdb_delete_local(struct net_bridge *br,
return;
}
- fdb_delete(br, f);
+ fdb_delete(br, f, true);
}
void br_fdb_find_delete_local(struct net_bridge *br,
@@ -356,7 +357,7 @@ void br_fdb_cleanup(struct work_struct *work)
} else {
spin_lock_bh(&br->hash_lock);
if (!hlist_unhashed(&f->fdb_node))
- fdb_delete(br, f);
+ fdb_delete(br, f, true);
spin_unlock_bh(&br->hash_lock);
}
}
@@ -376,7 +377,7 @@ void br_fdb_flush(struct net_bridge *br)
spin_lock_bh(&br->hash_lock);
hlist_for_each_entry_safe(f, tmp, &br->fdb_list, fdb_node) {
if (!f->is_static)
- fdb_delete(br, f);
+ fdb_delete(br, f, true);
}
spin_unlock_bh(&br->hash_lock);
}
@@ -405,7 +406,7 @@ void br_fdb_delete_by_port(struct net_bridge *br,
if (f->is_local)
fdb_delete_local(br, p, f);
else
- fdb_delete(br, f);
+ fdb_delete(br, f, true);
}
spin_unlock_bh(&br->hash_lock);
}
@@ -531,7 +532,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
return 0;
br_warn(br, "adding interface %s with same address as a received packet (addr:%pM, vlan:%u)\n",
source ? source->dev->name : br->dev->name, addr, vid);
- fdb_delete(br, fdb);
+ fdb_delete(br, fdb, true);
}
fdb = fdb_create(br, source, addr, vid, 1, 1);
@@ -539,7 +540,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
return -ENOMEM;
fdb_add_hw_addr(br, addr);
- fdb_notify(br, fdb, RTM_NEWNEIGH);
+ fdb_notify(br, fdb, RTM_NEWNEIGH, true);
return 0;
}
@@ -594,7 +595,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
fdb->added_by_user = 1;
if (unlikely(fdb_modified)) {
trace_br_fdb_update(br, source, addr, vid, added_by_user);
- fdb_notify(br, fdb, RTM_NEWNEIGH);
+ fdb_notify(br, fdb, RTM_NEWNEIGH, true);
}
}
} else {
@@ -605,7 +606,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
fdb->added_by_user = 1;
trace_br_fdb_update(br, source, addr, vid,
added_by_user);
- fdb_notify(br, fdb, RTM_NEWNEIGH);
+ fdb_notify(br, fdb, RTM_NEWNEIGH, true);
}
/* else we lose race and someone else inserts
* it first, don't bother updating
@@ -687,13 +688,15 @@ static inline size_t fdb_nlmsg_size(void)
}
static void fdb_notify(struct net_bridge *br,
- const struct net_bridge_fdb_entry *fdb, int type)
+ const struct net_bridge_fdb_entry *fdb, int type,
+ bool swdev_notify)
{
struct net *net = dev_net(br->dev);
struct sk_buff *skb;
int err = -ENOBUFS;
- br_switchdev_fdb_notify(fdb, type);
+ if (swdev_notify)
+ br_switchdev_fdb_notify(fdb, type);
skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
if (skb == NULL)
@@ -832,7 +835,7 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
fdb->used = jiffies;
if (modified) {
fdb->updated = jiffies;
- fdb_notify(br, fdb, RTM_NEWNEIGH);
+ fdb_notify(br, fdb, RTM_NEWNEIGH, true);
}
return 0;
@@ -856,7 +859,7 @@ static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br,
rcu_read_unlock();
local_bh_enable();
} else if (ndm->ndm_flags & NTF_EXT_LEARNED) {
- err = br_fdb_external_learn_add(br, p, addr, vid);
+ err = br_fdb_external_learn_add(br, p, addr, vid, true);
} else {
spin_lock_bh(&br->hash_lock);
err = fdb_add_entry(br, p, addr, ndm->ndm_state,
@@ -945,7 +948,7 @@ static int fdb_delete_by_addr_and_port(struct net_bridge *br,
if (!fdb || fdb->dst != p)
return -ENOENT;
- fdb_delete(br, fdb);
+ fdb_delete(br, fdb, true);
return 0;
}
@@ -1065,7 +1068,8 @@ void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
}
int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
- const unsigned char *addr, u16 vid)
+ const unsigned char *addr, u16 vid,
+ bool swdev_notify)
{
struct net_bridge_fdb_entry *fdb;
bool modified = false;
@@ -1083,7 +1087,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
goto err_unlock;
}
fdb->added_by_external_learn = 1;
- fdb_notify(br, fdb, RTM_NEWNEIGH);
+ fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
} else {
fdb->updated = jiffies;
@@ -1102,7 +1106,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
}
if (modified)
- fdb_notify(br, fdb, RTM_NEWNEIGH);
+ fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
}
err_unlock:
@@ -1112,7 +1116,8 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
}
int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
- const unsigned char *addr, u16 vid)
+ const unsigned char *addr, u16 vid,
+ bool swdev_notify)
{
struct net_bridge_fdb_entry *fdb;
int err = 0;
@@ -1121,7 +1126,7 @@ int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
fdb = br_fdb_find(br, addr, vid);
if (fdb && fdb->added_by_external_learn)
- fdb_delete(br, fdb);
+ fdb_delete(br, fdb, swdev_notify);
else
err = -ENOENT;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 1a50931..80a69b8 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -553,9 +553,11 @@ int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p);
void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p);
int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
- const unsigned char *addr, u16 vid);
+ const unsigned char *addr, u16 vid,
+ bool swdev_notify);
int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
- const unsigned char *addr, u16 vid);
+ const unsigned char *addr, u16 vid,
+ bool swdev_notify);
void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p,
const unsigned char *addr, u16 vid);
diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
index 71a03c4..35474d4 100644
--- a/net/bridge/br_switchdev.c
+++ b/net/bridge/br_switchdev.c
@@ -118,7 +118,7 @@ br_switchdev_fdb_call_notifiers(bool adding, const unsigned char *mac,
void
br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
{
- if (!fdb->added_by_user || !fdb->dst)
+ if (!fdb->dst)
return;
switch (type) {
--
2.4.11
^ permalink raw reply related
* [PATCH net-next] net: stmmac: Add support for U32 TC filter using Flexible RX Parser
From: Jose Abreu @ 2018-05-03 12:45 UTC (permalink / raw)
To: netdev
Cc: Jose Abreu, David S. Miller, Joao Pinto, Vitor Soares,
Giuseppe Cavallaro, Alexandre Torgue
This adds support for U32 filter by using an HW only feature called
Flexible RX Parser. This allow us to match any given packet field with a
pattern and accept/reject or even route the packet to a specific DMA
channel.
Right now we only support acception or rejection of frame and we only
support simple rules. Though, the Parser has the flexibility of jumping to
specific rules as an if condition so complex rules can be established.
This is only supported in GMAC5.10+.
The following commands can be used to test this code:
1) Setup an ingress qdisk:
# tc qdisc add dev eth0 handle ffff: ingress
2) Setup a filter (e.g. filter by IP):
# tc filter add dev eth0 parent ffff: protocol ip u32 match ip \
src 192.168.0.3 skip_sw action drop
In every tests performed we always used the "skip_sw" flag to make sure
only the RX Parser was involved.
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Vitor Soares <soares@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
---
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
drivers/net/ethernet/stmicro/stmmac/common.h | 5 +
drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 4 +
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 1 +
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 3 +
drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 194 ++++++++++++++
drivers/net/ethernet/stmicro/stmmac/dwmac5.h | 13 +
drivers/net/ethernet/stmicro/stmmac/hwif.c | 8 +
drivers/net/ethernet/stmicro/stmmac/hwif.h | 25 ++-
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 29 ++
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 62 +++++
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 293 +++++++++++++++++++++
12 files changed, 636 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index e3b578b..68e9e26 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \
dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- $(stmmac-y)
+ stmmac_tc.o $(stmmac-y)
# Ordering matters. Generic driver must be last.
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 627e905..a679cb7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -353,6 +353,10 @@ struct dma_features {
unsigned int rx_fifo_size;
/* Automotive Safety Package */
unsigned int asp;
+ /* RX Parser */
+ unsigned int frpsel;
+ unsigned int frpbs;
+ unsigned int frpes;
};
/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
@@ -412,6 +416,7 @@ struct mac_device_info {
const struct stmmac_dma_ops *dma;
const struct stmmac_mode_ops *mode;
const struct stmmac_hwtimestamp *ptp;
+ const struct stmmac_tc_ops *tc;
struct mii_regs mii; /* MII register Addresses */
struct mac_link link;
void __iomem *pcsr; /* vpointer to device CSRs */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
index 03eab90..6330a55 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
@@ -194,6 +194,9 @@ enum power_event {
/* MAC HW features3 bitmap */
#define GMAC_HW_FEAT_ASP GENMASK(29, 28)
+#define GMAC_HW_FEAT_FRPES GENMASK(14, 13)
+#define GMAC_HW_FEAT_FRPBS GENMASK(12, 11)
+#define GMAC_HW_FEAT_FRPSEL BIT(10)
/* MAC HW ADDR regs */
#define GMAC_HI_DCS GENMASK(18, 16)
@@ -202,6 +205,7 @@ enum power_event {
/* MTL registers */
#define MTL_OPERATION_MODE 0x00000c00
+#define MTL_FRPE BIT(15)
#define MTL_OPERATION_SCHALG_MASK GENMASK(6, 5)
#define MTL_OPERATION_SCHALG_WRR (0x0 << 5)
#define MTL_OPERATION_SCHALG_WFQ (0x1 << 5)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 7289b3b..a7121a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -795,6 +795,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x,
.safety_feat_config = dwmac5_safety_feat_config,
.safety_feat_irq_status = dwmac5_safety_feat_irq_status,
.safety_feat_dump = dwmac5_safety_feat_dump,
+ .rxp_config = dwmac5_rxp_config,
};
int dwmac4_setup(struct stmmac_priv *priv)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index d37d457..117c3a5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -379,6 +379,9 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
/* 5.10 Features */
dma_cap->asp = (hw_cap & GMAC_HW_FEAT_ASP) >> 28;
+ dma_cap->frpes = (hw_cap & GMAC_HW_FEAT_FRPES) >> 13;
+ dma_cap->frpbs = (hw_cap & GMAC_HW_FEAT_FRPBS) >> 11;
+ dma_cap->frpsel = (hw_cap & GMAC_HW_FEAT_FRPSEL) >> 10;
}
/* Enable/disable TSO feature and set MSS */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
index 2978550..50fd443 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
@@ -7,6 +7,7 @@
#include "common.h"
#include "dwmac4.h"
#include "dwmac5.h"
+#include "stmmac.h"
struct dwmac5_error_desc {
bool valid;
@@ -299,3 +300,196 @@ int dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
*desc = dwmac5_all_errors[module].desc[offset].desc;
return 0;
}
+
+static int dwmac5_rxp_disable(void __iomem *ioaddr)
+{
+ u32 val;
+ int ret;
+
+ val = readl(ioaddr + MTL_OPERATION_MODE);
+ val &= ~MTL_FRPE;
+ writel(val, ioaddr + MTL_OPERATION_MODE);
+
+ ret = readl_poll_timeout(ioaddr + MTL_RXP_CONTROL_STATUS, val,
+ val & RXPI, 1, 10000);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+static void dwmac5_rxp_enable(void __iomem *ioaddr)
+{
+ u32 val;
+
+ val = readl(ioaddr + MTL_OPERATION_MODE);
+ val |= MTL_FRPE;
+ writel(val, ioaddr + MTL_OPERATION_MODE);
+}
+
+static int dwmac5_rxp_update_single_entry(void __iomem *ioaddr,
+ struct stmmac_tc_entry *entry, int pos)
+{
+ int ret, i;
+
+ for (i = 0; i < (sizeof(entry->val) / sizeof(u32)); i++) {
+ int real_pos = pos * (sizeof(entry->val) / sizeof(u32)) + i;
+ u32 val;
+
+ /* Wait for ready */
+ ret = readl_poll_timeout(ioaddr + MTL_RXP_IACC_CTRL_STATUS,
+ val, !(val & STARTBUSY), 1, 10000);
+ if (ret)
+ return ret;
+
+ /* Write data */
+ val = *((u32 *)&entry->val + i);
+ writel(val, ioaddr + MTL_RXP_IACC_DATA);
+
+ /* Write pos */
+ val = real_pos & ADDR;
+ writel(val, ioaddr + MTL_RXP_IACC_CTRL_STATUS);
+
+ /* Write OP */
+ val |= WRRDN;
+ writel(val, ioaddr + MTL_RXP_IACC_CTRL_STATUS);
+
+ /* Start Write */
+ val |= STARTBUSY;
+ writel(val, ioaddr + MTL_RXP_IACC_CTRL_STATUS);
+
+ /* Wait for done */
+ ret = readl_poll_timeout(ioaddr + MTL_RXP_IACC_CTRL_STATUS,
+ val, !(val & STARTBUSY), 1, 10000);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct stmmac_tc_entry *dwmac5_rxp_get_next_entry(
+ struct stmmac_tc_entry *entries, unsigned int count,
+ u32 curr_prio)
+{
+ struct stmmac_tc_entry *entry;
+ u32 min_prio = ~0x0;
+ int i, min_prio_idx;
+ bool found = false;
+
+ for (i = count - 1; i >= 0; i--) {
+ entry = &entries[i];
+
+ /* Do not update unused entries */
+ if (!entry->in_use)
+ continue;
+ /* Do not update already updated entries (i.e. fragments) */
+ if (entry->in_hw)
+ continue;
+ /* Let last entry be updated last */
+ if (entry->is_last)
+ continue;
+ /* Do not return fragments */
+ if (entry->is_frag)
+ continue;
+ /* Check if we already checked this prio */
+ if (entry->prio < curr_prio)
+ continue;
+ /* Check if this is the minimum prio */
+ if (entry->prio < min_prio) {
+ min_prio = entry->prio;
+ min_prio_idx = i;
+ found = true;
+ }
+ }
+
+ if (found)
+ return &entries[min_prio_idx];
+ return NULL;
+}
+
+int dwmac5_rxp_config(void __iomem *ioaddr, struct stmmac_tc_entry *entries,
+ unsigned int count)
+{
+ struct stmmac_tc_entry *entry, *frag;
+ int i, ret, nve = 0;
+ u32 curr_prio = 0;
+ u32 old_val, val;
+
+ /* Force disable RX */
+ old_val = readl(ioaddr + GMAC_CONFIG);
+ val = old_val & ~GMAC_CONFIG_RE;
+ writel(val, ioaddr + GMAC_CONFIG);
+
+ /* Disable RX Parser */
+ ret = dwmac5_rxp_disable(ioaddr);
+ if (ret)
+ goto re_enable;
+
+ /* Set all entries as NOT in HW */
+ for (i = 0; i < count; i++) {
+ entry = &entries[i];
+ entry->in_hw = false;
+ }
+
+ /* Update entries by reverse order */
+ while (1) {
+ entry = dwmac5_rxp_get_next_entry(entries, count, curr_prio);
+ if (!entry)
+ break;
+
+ curr_prio = entry->prio;
+ frag = entry->frag_ptr;
+
+ /* Set special fragment requirements */
+ if (frag) {
+ entry->val.af = 0;
+ entry->val.rf = 0;
+ entry->val.nc = 1;
+ entry->val.ok_index = nve + 2;
+ }
+
+ ret = dwmac5_rxp_update_single_entry(ioaddr, entry, nve);
+ if (ret)
+ goto re_enable;
+
+ entry->table_pos = nve++;
+ entry->in_hw = true;
+
+ if (frag && !frag->in_hw) {
+ ret = dwmac5_rxp_update_single_entry(ioaddr, frag, nve);
+ if (ret)
+ goto re_enable;
+ frag->table_pos = nve++;
+ frag->in_hw = true;
+ }
+ }
+
+ if (!nve)
+ goto re_enable;
+
+ /* Update all pass entry */
+ for (i = 0; i < count; i++) {
+ entry = &entries[i];
+ if (!entry->is_last)
+ continue;
+
+ ret = dwmac5_rxp_update_single_entry(ioaddr, entry, nve);
+ if (ret)
+ goto re_enable;
+
+ entry->table_pos = nve++;
+ }
+
+ /* Assume n. of parsable entries == n. of valid entries */
+ val = (nve << 16) & NPE;
+ val |= nve & NVE;
+ writel(val, ioaddr + MTL_RXP_CONTROL_STATUS);
+
+ /* Enable RX Parser */
+ dwmac5_rxp_enable(ioaddr);
+
+re_enable:
+ /* Re-enable RX */
+ writel(old_val, ioaddr + GMAC_CONFIG);
+ return ret;
+}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
index bd4c466..a120cf8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
@@ -11,6 +11,17 @@
#define PRTYEN BIT(1)
#define TMOUTEN BIT(0)
+#define MTL_RXP_CONTROL_STATUS 0x00000ca0
+#define RXPI BIT(31)
+#define NPE GENMASK(23, 16)
+#define NVE GENMASK(7, 0)
+#define MTL_RXP_IACC_CTRL_STATUS 0x00000cb0
+#define STARTBUSY BIT(31)
+#define RXPEIEC GENMASK(22, 21)
+#define RXPEIEE BIT(20)
+#define WRRDN BIT(16)
+#define ADDR GENMASK(15, 0)
+#define MTL_RXP_IACC_DATA 0x00000cb4
#define MTL_ECC_CONTROL 0x00000cc0
#define TSOEE BIT(4)
#define MRXPEE BIT(3)
@@ -48,5 +59,7 @@ int dwmac5_safety_feat_irq_status(struct net_device *ndev,
struct stmmac_safety_stats *stats);
int dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
int index, unsigned long *count, const char **desc);
+int dwmac5_rxp_config(void __iomem *ioaddr, struct stmmac_tc_entry *entries,
+ unsigned int count);
#endif /* __DWMAC5_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 2b0a7e7..9acc8d2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -77,6 +77,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
const void *mac;
const void *hwtimestamp;
const void *mode;
+ const void *tc;
int (*setup)(struct stmmac_priv *priv);
int (*quirks)(struct stmmac_priv *priv);
} stmmac_hw[] = {
@@ -90,6 +91,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
.mac = &dwmac100_ops,
.hwtimestamp = &stmmac_ptp,
.mode = NULL,
+ .tc = NULL,
.setup = dwmac100_setup,
.quirks = stmmac_dwmac1_quirks,
}, {
@@ -101,6 +103,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
.mac = &dwmac1000_ops,
.hwtimestamp = &stmmac_ptp,
.mode = NULL,
+ .tc = NULL,
.setup = dwmac1000_setup,
.quirks = stmmac_dwmac1_quirks,
}, {
@@ -112,6 +115,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
.mac = &dwmac4_ops,
.hwtimestamp = &stmmac_ptp,
.mode = NULL,
+ .tc = NULL,
.setup = dwmac4_setup,
.quirks = stmmac_dwmac4_quirks,
}, {
@@ -123,6 +127,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
.mac = &dwmac410_ops,
.hwtimestamp = &stmmac_ptp,
.mode = &dwmac4_ring_mode_ops,
+ .tc = NULL,
.setup = dwmac4_setup,
.quirks = NULL,
}, {
@@ -134,6 +139,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
.mac = &dwmac410_ops,
.hwtimestamp = &stmmac_ptp,
.mode = &dwmac4_ring_mode_ops,
+ .tc = NULL,
.setup = dwmac4_setup,
.quirks = NULL,
}, {
@@ -145,6 +151,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
.mac = &dwmac510_ops,
.hwtimestamp = &stmmac_ptp,
.mode = &dwmac4_ring_mode_ops,
+ .tc = &dwmac510_tc_ops,
.setup = dwmac4_setup,
.quirks = NULL,
}
@@ -196,6 +203,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
mac->mac = entry->mac;
mac->ptp = entry->hwtimestamp;
mac->mode = entry->mode;
+ mac->tc = entry->tc;
priv->hw = mac;
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index bfad616..aaa2678 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -5,10 +5,12 @@
#ifndef __STMMAC_HWIF_H__
#define __STMMAC_HWIF_H__
+#include <linux/netdevice.h>
+
#define stmmac_do_void_callback(__priv, __module, __cname, __arg0, __args...) \
({ \
int __result = -EINVAL; \
- if ((__priv)->hw->__module->__cname) { \
+ if ((__priv)->hw->__module && (__priv)->hw->__module->__cname) { \
(__priv)->hw->__module->__cname((__arg0), ##__args); \
__result = 0; \
} \
@@ -17,7 +19,7 @@
#define stmmac_do_callback(__priv, __module, __cname, __arg0, __args...) \
({ \
int __result = -EINVAL; \
- if ((__priv)->hw->__module->__cname) \
+ if ((__priv)->hw->__module && (__priv)->hw->__module->__cname) \
__result = (__priv)->hw->__module->__cname((__arg0), ##__args); \
__result; \
})
@@ -232,6 +234,7 @@ struct stmmac_dma_ops {
struct net_device;
struct rgmii_adv;
struct stmmac_safety_stats;
+struct stmmac_tc_entry;
/* Helpers to program the MAC core */
struct stmmac_ops {
@@ -301,6 +304,9 @@ struct stmmac_ops {
struct stmmac_safety_stats *stats);
int (*safety_feat_dump)(struct stmmac_safety_stats *stats,
int index, unsigned long *count, const char **desc);
+ /* Flexible RX Parser */
+ int (*rxp_config)(void __iomem *ioaddr, struct stmmac_tc_entry *entries,
+ unsigned int count);
};
#define stmmac_core_init(__priv, __args...) \
@@ -365,6 +371,8 @@ struct stmmac_ops {
stmmac_do_callback(__priv, mac, safety_feat_irq_status, __args)
#define stmmac_safety_feat_dump(__priv, __args...) \
stmmac_do_callback(__priv, mac, safety_feat_dump, __args)
+#define stmmac_rxp_config(__priv, __args...) \
+ stmmac_do_callback(__priv, mac, rxp_config, __args)
/* PTP and HW Timer helpers */
struct stmmac_hwtimestamp {
@@ -419,6 +427,18 @@ struct stmmac_mode_ops {
stmmac_do_void_callback(__priv, mode, clean_desc3, __args)
struct stmmac_priv;
+struct tc_cls_u32_offload;
+
+struct stmmac_tc_ops {
+ int (*init)(struct stmmac_priv *priv);
+ int (*setup_cls_u32)(struct stmmac_priv *priv,
+ struct tc_cls_u32_offload *cls);
+};
+
+#define stmmac_tc_init(__priv, __args...) \
+ stmmac_do_callback(__priv, tc, init, __args)
+#define stmmac_tc_setup_cls_u32(__priv, __args...) \
+ stmmac_do_callback(__priv, tc, setup_cls_u32, __args)
extern const struct stmmac_ops dwmac100_ops;
extern const struct stmmac_dma_ops dwmac100_dma_ops;
@@ -429,6 +449,7 @@ struct stmmac_mode_ops {
extern const struct stmmac_ops dwmac410_ops;
extern const struct stmmac_dma_ops dwmac410_dma_ops;
extern const struct stmmac_ops dwmac510_ops;
+extern const struct stmmac_tc_ops dwmac510_tc_ops;
#define GMAC_VERSION 0x00000020 /* GMAC CORE Version */
#define GMAC4_VERSION 0x00000110 /* GMAC4+ CORE Version */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 2443f20..42fc76e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -76,6 +76,30 @@ struct stmmac_rx_queue {
struct napi_struct napi ____cacheline_aligned_in_smp;
};
+struct stmmac_tc_entry {
+ bool in_use;
+ bool in_hw;
+ bool is_last;
+ bool is_frag;
+ void *frag_ptr;
+ unsigned int table_pos;
+ u32 handle;
+ u32 prio;
+ struct {
+ u32 match_data;
+ u32 match_en;
+ u8 af:1;
+ u8 rf:1;
+ u8 im:1;
+ u8 nc:1;
+ u8 res1:4;
+ u8 frame_offset;
+ u8 ok_index;
+ u8 dma_ch_no;
+ u32 res2;
+ } __packed val;
+};
+
struct stmmac_priv {
/* Frequently used values are kept adjacent for cache effect */
u32 tx_count_frames;
@@ -151,6 +175,11 @@ struct stmmac_priv {
unsigned long state;
struct workqueue_struct *wq;
struct work_struct service_task;
+
+ /* TC Handling */
+ unsigned int tc_entries_max;
+ unsigned int tc_off_max;
+ struct stmmac_tc_entry *tc_entries;
};
enum stmmac_state {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 0135fd3..ba6049b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -45,6 +45,7 @@
#include <linux/seq_file.h>
#endif /* CONFIG_DEBUG_FS */
#include <linux/net_tstamp.h>
+#include <net/pkt_cls.h>
#include "stmmac_ptp.h"
#include "stmmac.h"
#include <linux/reset.h>
@@ -3786,6 +3787,61 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return ret;
}
+static int stmmac_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
+ void *cb_priv)
+{
+ struct stmmac_priv *priv = cb_priv;
+ int ret;
+
+ stmmac_disable_all_queues(priv);
+
+ switch (type) {
+ case TC_SETUP_CLSU32:
+ if (!(priv->dev->hw_features & NETIF_F_HW_TC))
+ ret = -EOPNOTSUPP;
+ else
+ ret = stmmac_tc_setup_cls_u32(priv, priv, type_data);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ stmmac_enable_all_queues(priv);
+ return ret;
+}
+
+static int stmmac_setup_tc_block(struct stmmac_priv *priv,
+ struct tc_block_offload *f)
+{
+ if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
+ return -EOPNOTSUPP;
+
+ switch (f->command) {
+ case TC_BLOCK_BIND:
+ return tcf_block_cb_register(f->block, stmmac_setup_tc_block_cb,
+ priv, priv);
+ case TC_BLOCK_UNBIND:
+ tcf_block_cb_unregister(f->block, stmmac_setup_tc_block_cb, priv);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
+ void *type_data)
+{
+ struct stmmac_priv *priv = netdev_priv(ndev);
+
+ switch (type) {
+ case TC_SETUP_BLOCK:
+ return stmmac_setup_tc_block(priv, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static int stmmac_set_mac_address(struct net_device *ndev, void *addr)
{
struct stmmac_priv *priv = netdev_priv(ndev);
@@ -4024,6 +4080,7 @@ static void stmmac_exit_fs(struct net_device *dev)
.ndo_set_rx_mode = stmmac_set_rx_mode,
.ndo_tx_timeout = stmmac_tx_timeout,
.ndo_do_ioctl = stmmac_ioctl,
+ .ndo_setup_tc = stmmac_setup_tc,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = stmmac_poll_controller,
#endif
@@ -4223,6 +4280,11 @@ int stmmac_dvr_probe(struct device *device,
ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM;
+ ret = stmmac_tc_init(priv, priv);
+ if (!ret) {
+ ndev->hw_features |= NETIF_F_HW_TC;
+ }
+
if ((priv->plat->tso_en) && (priv->dma_cap.tsoen)) {
ndev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
priv->tso = true;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
new file mode 100644
index 0000000..378e7a5
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac TC Handling (HW only)
+ */
+
+#include <net/pkt_cls.h>
+#include <net/tc_act/tc_gact.h>
+#include "common.h"
+#include "dwmac4.h"
+#include "dwmac5.h"
+#include "stmmac.h"
+
+static void tc_fill_all_pass_entry(struct stmmac_tc_entry *entry)
+{
+ memset(entry, 0, sizeof(*entry));
+ entry->in_use = true;
+ entry->is_last = true;
+ entry->is_frag = false;
+ entry->prio = ~0x0;
+ entry->handle = 0;
+ entry->val.match_data = 0x0;
+ entry->val.match_en = 0x0;
+ entry->val.af = 1;
+ entry->val.dma_ch_no = 0x0;
+}
+
+static struct stmmac_tc_entry *tc_find_entry(struct stmmac_priv *priv,
+ struct tc_cls_u32_offload *cls, bool free)
+{
+ struct stmmac_tc_entry *entry, *first = NULL, *dup = NULL;
+ u32 loc = cls->knode.handle;
+ int i;
+
+ for (i = 0; i < priv->tc_entries_max; i++) {
+ entry = &priv->tc_entries[i];
+ if (!entry->in_use && !first && free)
+ first = entry;
+ if (entry->handle == loc && !free)
+ dup = entry;
+ }
+
+ if (dup)
+ return dup;
+ if (first) {
+ first->handle = loc;
+ first->in_use = true;
+
+ /* Reset HW values */
+ memset(&first->val, 0, sizeof(first->val));
+ }
+
+ return first;
+}
+
+static int tc_fill_actions(struct stmmac_tc_entry *entry,
+ struct stmmac_tc_entry *frag, struct tc_cls_u32_offload *cls)
+{
+ struct stmmac_tc_entry *action_entry = entry;
+ const struct tc_action *act;
+ struct tcf_exts *exts;
+ LIST_HEAD(actions);
+
+ exts = cls->knode.exts;
+ if (!tcf_exts_has_actions(exts))
+ return -EINVAL;
+ if (frag)
+ action_entry = frag;
+
+ tcf_exts_to_list(exts, &actions);
+ list_for_each_entry(act, &actions, list) {
+ /* Accept */
+ if (is_tcf_gact_ok(act)) {
+ action_entry->val.af = 1;
+ break;
+ }
+ /* Drop */
+ if (is_tcf_gact_shot(act)) {
+ action_entry->val.rf = 1;
+ break;
+ }
+
+ /* Unsupported */
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int tc_fill_entry(struct stmmac_priv *priv,
+ struct tc_cls_u32_offload *cls)
+{
+ struct stmmac_tc_entry *entry, *frag = NULL;
+ struct tc_u32_sel *sel = cls->knode.sel;
+ u32 off, data, mask, real_off, rem;
+ u32 prio = cls->common.prio;
+ int ret;
+
+ /* Only 1 match per entry */
+ if (sel->nkeys <= 0 || sel->nkeys > 1)
+ return -EINVAL;
+
+ off = sel->keys[0].off << sel->offshift;
+ data = sel->keys[0].val;
+ mask = sel->keys[0].mask;
+
+ switch (ntohs(cls->common.protocol)) {
+ case ETH_P_ALL:
+ break;
+ case ETH_P_IP:
+ off += ETH_HLEN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (off > priv->tc_off_max)
+ return -EINVAL;
+
+ real_off = off / 4;
+ rem = off % 4;
+
+ entry = tc_find_entry(priv, cls, true);
+ if (!entry)
+ return -EINVAL;
+
+ if (rem) {
+ frag = tc_find_entry(priv, cls, true);
+ if (!frag) {
+ ret = -EINVAL;
+ goto err_unuse;
+ }
+
+ entry->frag_ptr = frag;
+ entry->val.match_en = (mask << (rem * 8)) &
+ GENMASK(31, rem * 8);
+ entry->val.match_data = (data << (rem * 8)) &
+ GENMASK(31, rem * 8);
+ entry->val.frame_offset = real_off;
+ entry->prio = prio;
+
+ frag->val.match_en = (mask >> (rem * 8)) &
+ GENMASK(rem * 8 - 1, 0);
+ frag->val.match_data = (data >> (rem * 8)) &
+ GENMASK(rem * 8 - 1, 0);
+ frag->val.frame_offset = real_off + 1;
+ frag->prio = prio;
+ frag->is_frag = true;
+ } else {
+ entry->frag_ptr = NULL;
+ entry->val.match_en = mask;
+ entry->val.match_data = data;
+ entry->val.frame_offset = real_off;
+ entry->prio = prio;
+ }
+
+ ret = tc_fill_actions(entry, frag, cls);
+ if (ret)
+ goto err_unuse;
+
+ return 0;
+
+err_unuse:
+ if (frag)
+ frag->in_use = false;
+ entry->in_use = false;
+ return ret;
+}
+
+static void tc_unfill_entry(struct stmmac_priv *priv,
+ struct tc_cls_u32_offload *cls)
+{
+ struct stmmac_tc_entry *entry;
+
+ entry = tc_find_entry(priv, cls, false);
+ if (!entry)
+ return;
+
+ entry->in_use = false;
+ if (entry->frag_ptr) {
+ entry = entry->frag_ptr;
+ entry->is_frag = false;
+ entry->in_use = false;
+ }
+}
+
+static int tc_config_knode(struct stmmac_priv *priv,
+ struct tc_cls_u32_offload *cls)
+{
+ int ret;
+
+ ret = tc_fill_entry(priv, cls);
+ if (ret)
+ return ret;
+
+ ret = stmmac_rxp_config(priv, priv->hw->pcsr, priv->tc_entries,
+ priv->tc_entries_max);
+ if (ret)
+ goto err_unfill;
+
+ return 0;
+
+err_unfill:
+ tc_unfill_entry(priv, cls);
+ return ret;
+}
+
+static int tc_delete_knode(struct stmmac_priv *priv,
+ struct tc_cls_u32_offload *cls)
+{
+ int ret;
+
+ /* Set entry and fragments as not used */
+ tc_unfill_entry(priv, cls);
+
+ ret = stmmac_rxp_config(priv, priv->hw->pcsr, priv->tc_entries,
+ priv->tc_entries_max);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int tc_setup_cls_u32(struct stmmac_priv *priv,
+ struct tc_cls_u32_offload *cls)
+{
+ switch (cls->command) {
+ case TC_CLSU32_REPLACE_KNODE:
+ tc_unfill_entry(priv, cls);
+ /* Fall through */
+ case TC_CLSU32_NEW_KNODE:
+ return tc_config_knode(priv, cls);
+ case TC_CLSU32_DELETE_KNODE:
+ return tc_delete_knode(priv, cls);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int tc_init(struct stmmac_priv *priv)
+{
+ struct dma_features *dma_cap = &priv->dma_cap;
+ unsigned int count;
+
+ if (!dma_cap->frpsel)
+ return -EINVAL;
+
+ switch (dma_cap->frpbs) {
+ case 0x0:
+ priv->tc_off_max = 64;
+ break;
+ case 0x1:
+ priv->tc_off_max = 128;
+ break;
+ case 0x2:
+ priv->tc_off_max = 256;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (dma_cap->frpes) {
+ case 0x0:
+ count = 64;
+ break;
+ case 0x1:
+ count = 128;
+ break;
+ case 0x2:
+ count = 256;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Reserve one last filter which lets all pass */
+ priv->tc_entries_max = count;
+ priv->tc_entries = devm_kzalloc(priv->device,
+ sizeof(*priv->tc_entries) * count, GFP_KERNEL);
+ if (!priv->tc_entries)
+ return -ENOMEM;
+
+ tc_fill_all_pass_entry(&priv->tc_entries[count - 1]);
+
+ dev_info(priv->device, "Enabling HW TC (entries=%d, max_off=%d)\n",
+ priv->tc_entries_max, priv->tc_off_max);
+ return 0;
+}
+
+const struct stmmac_tc_ops dwmac510_tc_ops = {
+ .init = tc_init,
+ .setup_cls_u32 = tc_setup_cls_u32,
+};
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] sctp: fix a potential missing-check bug
From: Marcelo Ricardo Leitner @ 2018-05-03 12:46 UTC (permalink / raw)
To: Wenwen Wang
Cc: Kangjie Lu, Vlad Yasevich, Neil Horman, David S. Miller,
open list:SCTP PROTOCOL, open list:NETWORKING [GENERAL],
open list
In-Reply-To: <CAAa=b7eebr23Pjs2LE0Ri0=gki8ZDAbLmfPWOqzWHO0i6E2aNA@mail.gmail.com>
On Thu, May 03, 2018 at 07:01:51AM -0500, Wenwen Wang wrote:
> On Wed, May 2, 2018 at 8:48 PM, Marcelo Ricardo Leitner
> <marcelo.leitner@gmail.com> wrote:
> > On Wed, May 02, 2018 at 08:27:05PM -0500, Wenwen Wang wrote:
> >> On Wed, May 2, 2018 at 8:24 PM, Marcelo Ricardo Leitner
> >> <marcelo.leitner@gmail.com> wrote:
> >> > On Wed, May 02, 2018 at 08:15:45PM -0500, Wenwen Wang wrote:
> >> >> In sctp_setsockopt_maxseg(), the integer 'val' is compared against min_len
> >> >> and max_len to check whether it is in the appropriate range. If it is not,
> >> >> an error code -EINVAL will be returned. This is enforced by a security
> >> >> check. But, this check is only executed when 'val' is not 0. In fact, if
> >> >> 'val' is 0, it will be assigned with a new value (if the return value of
> >> >> the function sctp_id2assoc() is not 0) in the following execution. However,
> >> >> this new value of 'val' is not checked before it is used to assigned to
> >> >> asoc->user_frag. That means it is possible that the new value of 'val'
> >> >> could be out of the expected range. This can cause security issues
> >> >> such as buffer overflows, e.g., the new value of 'val' is used as an index
> >> >> to access a buffer.
> >> >>
> >> >> This patch inserts a check for the new value of 'val' to see if it is in
> >> >> the expected range. If it is not, an error code -EINVAL will be returned.
> >> >>
> >> >> Signed-off-by: Wenwen Wang <wang6495@umn.edu>
> >> >> ---
> >> >> net/sctp/socket.c | 22 +++++++++++-----------
> >> >> 1 file changed, 11 insertions(+), 11 deletions(-)
> >> >
> >> > ?
> >> > This patch is the same as previous one. git send-email <old file>
> >> > maybe?
> >> >
> >> > Marcelo
> >>
> >> Thanks for your suggestion, Marcelo. I can send the old file. But, I
> >> have added a line of comment in this patch.
> >
> > I meant if you had sent the old patch again by accident, because you
> > said you worked on an old version of the tree, but then posted a patch
> > that also doesn't use the new MTU function I mentioned.
> >
> > Marcelo
>
> I worked on the latest kernel. But, I didn't find the MTU function
> sctp_mtu_payload().
Which tree are you using?
[a] git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
or
[b] git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
?
The function isn't on [a] yet, but it is on [b].
Marcelo
^ permalink raw reply
* Re: [PATCH net-next mlxsw v2 0/2] bridge: FDB: Notify about removal of non-user-added entries
From: Petr Machata @ 2018-05-03 12:48 UTC (permalink / raw)
To: netdev
Cc: bridge, jiri, idosch, ivecera, davem, stephen, andrew,
vivien.didelot, f.fainelli
In-Reply-To: <cover.1525350809.git.petrm@mellanox.com>
This is of course not meant for "mlxsw" :-/
Petr
^ permalink raw reply
* Re: [PATCH net-next] net: core: rework skb_probe_transport_header()
From: Jason Wang @ 2018-05-03 12:55 UTC (permalink / raw)
To: Paolo Abeni, netdev; +Cc: David S. Miller, Eric Dumazet
In-Reply-To: <7cbdf466f4a1bf44ddbb948428dc7bb0dad091a7.1525340013.git.pabeni@redhat.com>
On 2018年05月03日 17:35, Paolo Abeni wrote:
> When the transport header is not available, skb_probe_transport_header()
> resorts to fully dissect the flow keys, even if it only needs the
> ransport offset. We can obtain the latter using a simpler flow dissector -
> flow_keys_buf_dissector - and a smaller struct for key storage.
>
> The above gives ~50% performance improvement in micro benchmarking around
> skb_probe_transport_header(), mostly due to the smaller memset. Small, but
> measurable improvement is measured also in macro benchmarking - raw xmit
> tput from a VM.
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
> include/linux/skbuff.h | 7 +++++--
> include/net/flow_dissector.h | 5 +++++
> net/core/flow_dissector.c | 1 +
> 3 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index 908d66e55b14..63cb523d3519 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -2350,11 +2350,14 @@ static inline void skb_pop_mac_header(struct sk_buff *skb)
> static inline void skb_probe_transport_header(struct sk_buff *skb,
> const int offset_hint)
> {
> - struct flow_keys keys;
> + struct flow_keys_basic keys;
>
> if (skb_transport_header_was_set(skb))
> return;
> - else if (skb_flow_dissect_flow_keys(skb, &keys, 0))
> +
> + memset(&keys, 0, sizeof(keys));
> + if (__skb_flow_dissect(skb, &flow_keys_buf_dissector, &keys,
> + 0, 0, 0, 0, 0))
> skb_set_transport_header(skb, keys.control.thoff);
> else
> skb_set_transport_header(skb, offset_hint);
> diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
> index 9a074776f70b..e81dab6e9ac6 100644
> --- a/include/net/flow_dissector.h
> +++ b/include/net/flow_dissector.h
> @@ -226,6 +226,11 @@ struct flow_dissector {
> unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
> };
>
> +struct flow_keys_basic {
> + struct flow_dissector_key_control control;
> + struct flow_dissector_key_basic basic;
> +};
> +
> struct flow_keys {
> struct flow_dissector_key_control control;
> #define FLOW_KEYS_HASH_START_FIELD basic
> diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
> index d29f09bc5ff9..ac7b4de4a0f0 100644
> --- a/net/core/flow_dissector.c
> +++ b/net/core/flow_dissector.c
> @@ -1418,6 +1418,7 @@ struct flow_dissector flow_keys_dissector __read_mostly;
> EXPORT_SYMBOL(flow_keys_dissector);
>
> struct flow_dissector flow_keys_buf_dissector __read_mostly;
> +EXPORT_SYMBOL(flow_keys_buf_dissector);
>
> static int __init init_default_flow_dissectors(void)
> {
Acked-by: Jason Wang <jasowang@redhat.com>
Just curious, I believe this happens only when csum offload is disabled
which is not the common case?
Thanks
^ permalink raw reply
* Re: [PATCH net-next mlxsw v2 2/2] net: bridge: Notify about !added_by_user FDB entries
From: Nikolay Aleksandrov @ 2018-05-03 12:56 UTC (permalink / raw)
To: Petr Machata, netdev, bridge
Cc: jiri, idosch, ivecera, davem, stephen, andrew, vivien.didelot,
f.fainelli
In-Reply-To: <33ac8ce3fcd084190c5797a409ebd7858f7d47db.1525350809.git.petrm@mellanox.com>
On 03/05/18 15:43, Petr Machata wrote:
> Do not automatically bail out on sending notifications about activity on
> non-user-added FDB entries. Instead, notify about this activity except
> for cases where the activity itself originates in a notification, to
> avoid sending duplicate notifications.
>
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> ---
> net/bridge/br.c | 4 ++--
> net/bridge/br_fdb.c | 47 ++++++++++++++++++++++++++---------------------
> net/bridge/br_private.h | 6 ++++--
> net/bridge/br_switchdev.c | 2 +-
> 4 files changed, 33 insertions(+), 26 deletions(-)
>
Thanks, looks good to me! In the future please add the reviewers to the CC list
when sending a v2, I actually missed the v2 set and saw your reply to the cover
letter patch later.
Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
^ permalink raw reply
* Re: [RFC PATCH 3/5] net: macb: Add pm runtime support
From: Claudiu Beznea @ 2018-05-03 12:59 UTC (permalink / raw)
To: Harini Katakam
Cc: Nicolas Ferre, David Miller, netdev, linux-kernel, michals,
appanad, Shubhrajyoti Datta
In-Reply-To: <CAFcVECKWz6bGZpg7UF=4hObUjca12Oq5NbE0SBL+v=1grJP8YA@mail.gmail.com>
On 03.05.2018 14:13, Harini Katakam wrote:
> Hi Claudiu,
>
> On Thu, May 3, 2018 at 3:39 PM, Claudiu Beznea
> <Claudiu.Beznea@microchip.com> wrote:
>>
>>
>> On 22.03.2018 15:51, harinikatakamlinux@gmail.com wrote:
>>> From: Harini Katakam <harinik@xilinx.com>
> <snip>
>> I would use a "goto" instruction, e.g.:
>> value = -ETIMEDOUT;
>> goto out;
>>
>
> Will do
>
>>
>> Below, in macb_open() you have a return err; case:
>> err = macb_alloc_consistent(bp);
>> if (err) {
>> netdev_err(dev, "Unable to allocate DMA memory (error %d)\n",
>> err);
>> return err;
>> }
>>
>> You have to undo pm_runtime_get_sync() with pm_runtime_put_sync() or something
>> similar to decrement dev->power.usage_count.
>
> Will do
>
> <snip>
>>> @@ -4104,11 +4145,16 @@ static int macb_remove(struct platform_device *pdev)
>>> mdiobus_free(bp->mii_bus);
>>>
>>> unregister_netdev(dev);
>>> - clk_disable_unprepare(bp->tx_clk);
>>> - clk_disable_unprepare(bp->hclk);
>>> - clk_disable_unprepare(bp->pclk);
>>> - clk_disable_unprepare(bp->rx_clk);
>>> - clk_disable_unprepare(bp->tsu_clk);
>>> + pm_runtime_disable(&pdev->dev);
>>> + pm_runtime_dont_use_autosuspend(&pdev->dev);
>>> + if (!pm_runtime_suspended(&pdev->dev)) {
>>> + clk_disable_unprepare(bp->tx_clk);
>>> + clk_disable_unprepare(bp->hclk);
>>> + clk_disable_unprepare(bp->pclk);
>>> + clk_disable_unprepare(bp->rx_clk);
>>> + clk_disable_unprepare(bp->tsu_clk);
>>> + pm_runtime_set_suspended(&pdev->dev);
>>
>> This is driver remove function. Shouldn't clocks be removed?
>
> clk_disable_unprepare IS being done here.
> The check for !pm_runtime_suspended is just to make sure the
> clocks are not already removed (in runtime_suspend).
Could this happen? Looking over code, starting with
platform_driver_unregister() it looks to me that the runtime resume
is called just before driver remove is called.
platform_driver_unregister() ->
driver_unregister() ->
bus_remove_driver() ->
driver_detach() ->
device_release_driver_internal() ->
__device_release_driver()
{
// ...
pm_runtime_get_sync(dev); // runtime resume
pm_runtime_clean_up_links(dev);
// ...
pm_runtime_put_sync(dev);
if (dev->bus && dev->bus->remove)
dev->bus->remove(dev);
else if (drv->remove)
drv->remove(dev);
// ...
}
Thank you,
Claudiu
>
> Regards,
> Harini
>
^ permalink raw reply
* Re: [PATCH net-next mlxsw v2 1/2] switchdev: Add fdb.added_by_user to switchdev notifications
From: Ivan Vecera @ 2018-05-03 12:59 UTC (permalink / raw)
To: Petr Machata, netdev, bridge
Cc: jiri, idosch, davem, stephen, andrew, vivien.didelot, f.fainelli
In-Reply-To: <36a671d4d30995902f5c3acc68cf8317f8ce05cb.1525350809.git.petrm@mellanox.com>
On 3.5.2018 14:43, Petr Machata wrote:
> The following patch enables sending notifications also for events on FDB
> entries that weren't added by the user. Give the drivers the information
> necessary to distinguish between the two origins of FDB entries.
>
> To maintain the current behavior, have switchdev-implementing drivers
> bail out on notifications about non-user-added FDB entries. In case of
> mlxsw driver, allow a call to mlxsw_sp_span_respin() so that SPAN over
> bridge catches up with the changed FDB.
>
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
> ---
> drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 4 ++++
> drivers/net/ethernet/rocker/rocker_main.c | 2 ++
> include/net/switchdev.h | 1 +
> net/bridge/br_switchdev.c | 10 +++++++---
> net/dsa/slave.c | 5 ++++-
> 5 files changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
> index 1af99fe..3973d90 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
> +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
> @@ -2270,6 +2270,8 @@ static void mlxsw_sp_switchdev_event_work(struct work_struct *work)
> switch (switchdev_work->event) {
> case SWITCHDEV_FDB_ADD_TO_DEVICE:
> fdb_info = &switchdev_work->fdb_info;
> + if (!fdb_info->added_by_user)
> + break;
> err = mlxsw_sp_port_fdb_set(mlxsw_sp_port, fdb_info, true);
> if (err)
> break;
> @@ -2279,6 +2281,8 @@ static void mlxsw_sp_switchdev_event_work(struct work_struct *work)
> break;
> case SWITCHDEV_FDB_DEL_TO_DEVICE:
> fdb_info = &switchdev_work->fdb_info;
> + if (!fdb_info->added_by_user)
> + break;
> mlxsw_sp_port_fdb_set(mlxsw_sp_port, fdb_info, false);
> break;
> case SWITCHDEV_FDB_ADD_TO_BRIDGE: /* fall through */
> diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
> index 056cb60..152d694 100644
> --- a/drivers/net/ethernet/rocker/rocker_main.c
> +++ b/drivers/net/ethernet/rocker/rocker_main.c
> @@ -2783,6 +2783,8 @@ static int rocker_switchdev_event(struct notifier_block *unused,
> switch (event) {
> case SWITCHDEV_FDB_ADD_TO_DEVICE: /* fall through */
> case SWITCHDEV_FDB_DEL_TO_DEVICE:
> + if (!fdb_info->added_by_user)
> + break;
> memcpy(&switchdev_work->fdb_info, ptr,
> sizeof(switchdev_work->fdb_info));
> switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> index 39bc855..d574ce6 100644
> --- a/include/net/switchdev.h
> +++ b/include/net/switchdev.h
> @@ -155,6 +155,7 @@ struct switchdev_notifier_fdb_info {
> struct switchdev_notifier_info info; /* must be first */
> const unsigned char *addr;
> u16 vid;
> + bool added_by_user;
> };
>
> static inline struct net_device *
> diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
> index ee775f4..71a03c4 100644
> --- a/net/bridge/br_switchdev.c
> +++ b/net/bridge/br_switchdev.c
> @@ -102,13 +102,15 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
>
> static void
> br_switchdev_fdb_call_notifiers(bool adding, const unsigned char *mac,
> - u16 vid, struct net_device *dev)
> + u16 vid, struct net_device *dev,
> + bool added_by_user)
> {
> struct switchdev_notifier_fdb_info info;
> unsigned long notifier_type;
>
> info.addr = mac;
> info.vid = vid;
> + info.added_by_user = added_by_user;
> notifier_type = adding ? SWITCHDEV_FDB_ADD_TO_DEVICE : SWITCHDEV_FDB_DEL_TO_DEVICE;
> call_switchdev_notifiers(notifier_type, dev, &info.info);
> }
> @@ -123,12 +125,14 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
> case RTM_DELNEIGH:
> br_switchdev_fdb_call_notifiers(false, fdb->key.addr.addr,
> fdb->key.vlan_id,
> - fdb->dst->dev);
> + fdb->dst->dev,
> + fdb->added_by_user);
> break;
> case RTM_NEWNEIGH:
> br_switchdev_fdb_call_notifiers(true, fdb->key.addr.addr,
> fdb->key.vlan_id,
> - fdb->dst->dev);
> + fdb->dst->dev,
> + fdb->added_by_user);
> break;
> }
> }
> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
> index f3fb3a0..c287f1e 100644
> --- a/net/dsa/slave.c
> +++ b/net/dsa/slave.c
> @@ -1441,6 +1441,7 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
> unsigned long event, void *ptr)
> {
> struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
> + struct switchdev_notifier_fdb_info *fdb_info = ptr;
> struct dsa_switchdev_event_work *switchdev_work;
>
> if (!dsa_slave_dev_check(dev))
> @@ -1458,8 +1459,10 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
> switch (event) {
> case SWITCHDEV_FDB_ADD_TO_DEVICE: /* fall through */
> case SWITCHDEV_FDB_DEL_TO_DEVICE:
> + if (!fdb_info->added_by_user)
> + break;
> if (dsa_slave_switchdev_fdb_work_init(switchdev_work,
> - ptr))
> + fdb_info))
> goto err_fdb_work_init;
> dev_hold(dev);
> break;
>
LGTM
Acked-by: Ivan Vecera <ivecera@redhat.com>
^ permalink raw reply
* Re: [PATCH net-next mlxsw v2 2/2] net: bridge: Notify about !added_by_user FDB entries
From: Ivan Vecera @ 2018-05-03 13:00 UTC (permalink / raw)
To: Petr Machata, netdev, bridge
Cc: jiri, idosch, davem, stephen, andrew, vivien.didelot, f.fainelli
In-Reply-To: <33ac8ce3fcd084190c5797a409ebd7858f7d47db.1525350809.git.petrm@mellanox.com>
On 3.5.2018 14:43, Petr Machata wrote:
> Do not automatically bail out on sending notifications about activity on
> non-user-added FDB entries. Instead, notify about this activity except
> for cases where the activity itself originates in a notification, to
> avoid sending duplicate notifications.
>
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> ---
> net/bridge/br.c | 4 ++--
> net/bridge/br_fdb.c | 47 ++++++++++++++++++++++++++---------------------
> net/bridge/br_private.h | 6 ++++--
> net/bridge/br_switchdev.c | 2 +-
> 4 files changed, 33 insertions(+), 26 deletions(-)
>
> diff --git a/net/bridge/br.c b/net/bridge/br.c
> index 671d13c..c6b033e 100644
> --- a/net/bridge/br.c
> +++ b/net/bridge/br.c
> @@ -141,7 +141,7 @@ static int br_switchdev_event(struct notifier_block *unused,
> case SWITCHDEV_FDB_ADD_TO_BRIDGE:
> fdb_info = ptr;
> err = br_fdb_external_learn_add(br, p, fdb_info->addr,
> - fdb_info->vid);
> + fdb_info->vid, false);
> if (err) {
> err = notifier_from_errno(err);
> break;
> @@ -152,7 +152,7 @@ static int br_switchdev_event(struct notifier_block *unused,
> case SWITCHDEV_FDB_DEL_TO_BRIDGE:
> fdb_info = ptr;
> err = br_fdb_external_learn_del(br, p, fdb_info->addr,
> - fdb_info->vid);
> + fdb_info->vid, false);
> if (err)
> err = notifier_from_errno(err);
> break;
> diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
> index a1c409c..b19e310 100644
> --- a/net/bridge/br_fdb.c
> +++ b/net/bridge/br_fdb.c
> @@ -40,7 +40,7 @@ static struct kmem_cache *br_fdb_cache __read_mostly;
> static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
> const unsigned char *addr, u16 vid);
> static void fdb_notify(struct net_bridge *br,
> - const struct net_bridge_fdb_entry *, int);
> + const struct net_bridge_fdb_entry *, int, bool);
>
> int __init br_fdb_init(void)
> {
> @@ -195,7 +195,8 @@ static void fdb_del_hw_addr(struct net_bridge *br, const unsigned char *addr)
> }
> }
>
> -static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f)
> +static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f,
> + bool swdev_notify)
> {
> trace_fdb_delete(br, f);
>
> @@ -205,7 +206,7 @@ static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f)
> hlist_del_init_rcu(&f->fdb_node);
> rhashtable_remove_fast(&br->fdb_hash_tbl, &f->rhnode,
> br_fdb_rht_params);
> - fdb_notify(br, f, RTM_DELNEIGH);
> + fdb_notify(br, f, RTM_DELNEIGH, swdev_notify);
> call_rcu(&f->rcu, fdb_rcu_free);
> }
>
> @@ -241,7 +242,7 @@ static void fdb_delete_local(struct net_bridge *br,
> return;
> }
>
> - fdb_delete(br, f);
> + fdb_delete(br, f, true);
> }
>
> void br_fdb_find_delete_local(struct net_bridge *br,
> @@ -356,7 +357,7 @@ void br_fdb_cleanup(struct work_struct *work)
> } else {
> spin_lock_bh(&br->hash_lock);
> if (!hlist_unhashed(&f->fdb_node))
> - fdb_delete(br, f);
> + fdb_delete(br, f, true);
> spin_unlock_bh(&br->hash_lock);
> }
> }
> @@ -376,7 +377,7 @@ void br_fdb_flush(struct net_bridge *br)
> spin_lock_bh(&br->hash_lock);
> hlist_for_each_entry_safe(f, tmp, &br->fdb_list, fdb_node) {
> if (!f->is_static)
> - fdb_delete(br, f);
> + fdb_delete(br, f, true);
> }
> spin_unlock_bh(&br->hash_lock);
> }
> @@ -405,7 +406,7 @@ void br_fdb_delete_by_port(struct net_bridge *br,
> if (f->is_local)
> fdb_delete_local(br, p, f);
> else
> - fdb_delete(br, f);
> + fdb_delete(br, f, true);
> }
> spin_unlock_bh(&br->hash_lock);
> }
> @@ -531,7 +532,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
> return 0;
> br_warn(br, "adding interface %s with same address as a received packet (addr:%pM, vlan:%u)\n",
> source ? source->dev->name : br->dev->name, addr, vid);
> - fdb_delete(br, fdb);
> + fdb_delete(br, fdb, true);
> }
>
> fdb = fdb_create(br, source, addr, vid, 1, 1);
> @@ -539,7 +540,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
> return -ENOMEM;
>
> fdb_add_hw_addr(br, addr);
> - fdb_notify(br, fdb, RTM_NEWNEIGH);
> + fdb_notify(br, fdb, RTM_NEWNEIGH, true);
> return 0;
> }
>
> @@ -594,7 +595,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
> fdb->added_by_user = 1;
> if (unlikely(fdb_modified)) {
> trace_br_fdb_update(br, source, addr, vid, added_by_user);
> - fdb_notify(br, fdb, RTM_NEWNEIGH);
> + fdb_notify(br, fdb, RTM_NEWNEIGH, true);
> }
> }
> } else {
> @@ -605,7 +606,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
> fdb->added_by_user = 1;
> trace_br_fdb_update(br, source, addr, vid,
> added_by_user);
> - fdb_notify(br, fdb, RTM_NEWNEIGH);
> + fdb_notify(br, fdb, RTM_NEWNEIGH, true);
> }
> /* else we lose race and someone else inserts
> * it first, don't bother updating
> @@ -687,13 +688,15 @@ static inline size_t fdb_nlmsg_size(void)
> }
>
> static void fdb_notify(struct net_bridge *br,
> - const struct net_bridge_fdb_entry *fdb, int type)
> + const struct net_bridge_fdb_entry *fdb, int type,
> + bool swdev_notify)
> {
> struct net *net = dev_net(br->dev);
> struct sk_buff *skb;
> int err = -ENOBUFS;
>
> - br_switchdev_fdb_notify(fdb, type);
> + if (swdev_notify)
> + br_switchdev_fdb_notify(fdb, type);
>
> skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
> if (skb == NULL)
> @@ -832,7 +835,7 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
> fdb->used = jiffies;
> if (modified) {
> fdb->updated = jiffies;
> - fdb_notify(br, fdb, RTM_NEWNEIGH);
> + fdb_notify(br, fdb, RTM_NEWNEIGH, true);
> }
>
> return 0;
> @@ -856,7 +859,7 @@ static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br,
> rcu_read_unlock();
> local_bh_enable();
> } else if (ndm->ndm_flags & NTF_EXT_LEARNED) {
> - err = br_fdb_external_learn_add(br, p, addr, vid);
> + err = br_fdb_external_learn_add(br, p, addr, vid, true);
> } else {
> spin_lock_bh(&br->hash_lock);
> err = fdb_add_entry(br, p, addr, ndm->ndm_state,
> @@ -945,7 +948,7 @@ static int fdb_delete_by_addr_and_port(struct net_bridge *br,
> if (!fdb || fdb->dst != p)
> return -ENOENT;
>
> - fdb_delete(br, fdb);
> + fdb_delete(br, fdb, true);
>
> return 0;
> }
> @@ -1065,7 +1068,8 @@ void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
> }
>
> int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
> - const unsigned char *addr, u16 vid)
> + const unsigned char *addr, u16 vid,
> + bool swdev_notify)
> {
> struct net_bridge_fdb_entry *fdb;
> bool modified = false;
> @@ -1083,7 +1087,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
> goto err_unlock;
> }
> fdb->added_by_external_learn = 1;
> - fdb_notify(br, fdb, RTM_NEWNEIGH);
> + fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
> } else {
> fdb->updated = jiffies;
>
> @@ -1102,7 +1106,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
> }
>
> if (modified)
> - fdb_notify(br, fdb, RTM_NEWNEIGH);
> + fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
> }
>
> err_unlock:
> @@ -1112,7 +1116,8 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
> }
>
> int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
> - const unsigned char *addr, u16 vid)
> + const unsigned char *addr, u16 vid,
> + bool swdev_notify)
> {
> struct net_bridge_fdb_entry *fdb;
> int err = 0;
> @@ -1121,7 +1126,7 @@ int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
>
> fdb = br_fdb_find(br, addr, vid);
> if (fdb && fdb->added_by_external_learn)
> - fdb_delete(br, fdb);
> + fdb_delete(br, fdb, swdev_notify);
> else
> err = -ENOENT;
>
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 1a50931..80a69b8 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -553,9 +553,11 @@ int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
> int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p);
> void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p);
> int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
> - const unsigned char *addr, u16 vid);
> + const unsigned char *addr, u16 vid,
> + bool swdev_notify);
> int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
> - const unsigned char *addr, u16 vid);
> + const unsigned char *addr, u16 vid,
> + bool swdev_notify);
> void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p,
> const unsigned char *addr, u16 vid);
>
> diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
> index 71a03c4..35474d4 100644
> --- a/net/bridge/br_switchdev.c
> +++ b/net/bridge/br_switchdev.c
> @@ -118,7 +118,7 @@ br_switchdev_fdb_call_notifiers(bool adding, const unsigned char *mac,
> void
> br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
> {
> - if (!fdb->added_by_user || !fdb->dst)
> + if (!fdb->dst)
> return;
>
> switch (type) {
>
Acked-by: Ivan Vecera <ivecera@redhat.com>
^ permalink raw reply
* Re: [PATCH v3 09/20] iommu: Remove depends on HAS_DMA in case of platform dependency
From: Joerg Roedel @ 2018-05-03 13:02 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Ulf Hansson, Wolfram Sang, linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-fpga-u79uwXL29TY76Z2rM5mHXA,
linux-remoteproc-u79uwXL29TY76Z2rM5mHXA,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Bjorn Andersson, Eric Anholt,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux1394-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Christoph Hellwig, Stefan Wahren, Boris Brezillon, Herbert Xu,
Richard Weinberger, Jassi Brar, Marek Vasut,
linux-serial-u79uwXL29TY76Z2rM5mHXA, Matias Bjorling,
linux-media-u79uwXL29TY76Z2rM5mHXA, Ohad Ben-Cohen,
devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b, Alan Tull,
Bartlomiej Zolnierkiewicz <
In-Reply-To: <1523987360-18760-10-git-send-email-geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
On Tue, Apr 17, 2018 at 07:49:09PM +0200, Geert Uytterhoeven wrote:
> Remove dependencies on HAS_DMA where a Kconfig symbol depends on another
> symbol that implies HAS_DMA, and, optionally, on "|| COMPILE_TEST".
> In most cases this other symbol is an architecture or platform specific
> symbol, or PCI.
>
> Generic symbols and drivers without platform dependencies keep their
> dependencies on HAS_DMA, to prevent compiling subsystems or drivers that
> cannot work anyway.
>
> This simplifies the dependencies, and allows to improve compile-testing.
>
> Signed-off-by: Geert Uytterhoeven <geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
> Reviewed-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Acked-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
> Acked-by: Joerg Roedel <jroedel-l3A5Bk7waGM@public.gmane.org>
Applied, thanks.
^ permalink raw reply
* [PATCH] dt-bindings: can: rcar_can: Fix R8A7796 SoC name
From: Geert Uytterhoeven @ 2018-05-03 13:02 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde, Rob Herring, Mark Rutland
Cc: Chris Paterson, linux-can, netdev, devicetree, linux-renesas-soc,
Geert Uytterhoeven
R8A7796 is R-Car M3-W.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Documentation/devicetree/bindings/net/can/rcar_canfd.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
index 93c3a6ae32f995e9..1a4ee1d2506de532 100644
--- a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
+++ b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
@@ -5,7 +5,7 @@ Required properties:
- compatible: Must contain one or more of the following:
- "renesas,rcar-gen3-canfd" for R-Car Gen3 compatible controller.
- "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller.
- - "renesas,r8a7796-canfd" for R8A7796 (R-Car M3) compatible controller.
+ - "renesas,r8a7796-canfd" for R8A7796 (R-Car M3-W) compatible controller.
When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first, followed by the
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net-next mlxsw v2 2/2] net: bridge: Notify about !added_by_user FDB entries
From: Petr Machata @ 2018-05-03 13:07 UTC (permalink / raw)
To: Nikolay Aleksandrov
Cc: netdev, bridge, jiri, idosch, ivecera, davem, stephen, andrew,
vivien.didelot, f.fainelli
In-Reply-To: <39b65224-cd35-4716-1a8c-cc1bfaff0654@cumulusnetworks.com>
Nikolay Aleksandrov <nikolay@cumulusnetworks.com> writes:
> On 03/05/18 15:43, Petr Machata wrote:
>> Do not automatically bail out on sending notifications about activity on
>> non-user-added FDB entries. Instead, notify about this activity except
>> for cases where the activity itself originates in a notification, to
>> avoid sending duplicate notifications.
>>
>> Signed-off-by: Petr Machata <petrm@mellanox.com>
>> ---
>> net/bridge/br.c | 4 ++--
>> net/bridge/br_fdb.c | 47 ++++++++++++++++++++++++++---------------------
>> net/bridge/br_private.h | 6 ++++--
>> net/bridge/br_switchdev.c | 2 +-
>> 4 files changed, 33 insertions(+), 26 deletions(-)
>>
>
> Thanks, looks good to me! In the future please add the reviewers to the CC list
> when sending a v2, I actually missed the v2 set and saw your reply to the cover
> letter patch later.
Sorry, I'm still tweaking my process for direct submission after going
almost exclusively through mlxsw for so long!
> Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Thanks,
Petr
^ permalink raw reply
* Re: [PATCH v1 net-next] net: dsa: mv88e6xxx: Fix name string for 88E6141
From: Andrew Lunn @ 2018-05-03 13:11 UTC (permalink / raw)
To: Marek Behún
Cc: netdev, Greg Kroah-Hartman, Vivien Didelot, Arkadi Sharshevsky,
David S . Miller
In-Reply-To: <20180503130655.23275-1-marek.behun@nic.cz>
On Thu, May 03, 2018 at 03:06:55PM +0200, Marek Behún wrote:
> The structure was copied from 88E6341 but the name was not changed.
>
> Signed-off-by: Marek Behun <marek.behun@nic.cz>
Hi Marek
Which tree is this against?
> ---
> drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
> index e9600a82dc83..fae362020305 100644
> --- a/drivers/net/dsa/mv88e6xxx/chip.c
> +++ b/drivers/net/dsa/mv88e6xxx/chip.c
> @@ -3206,7 +3206,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
> [MV88E6141] = {
> .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
> .family = MV88E6XXX_FAMILY_6341,
> - .name = "Marvell 88E6341",
> + .name = "Marvell 88E6141",
> .num_databases = 4096,
> .num_ports = 6,
> .max_vid = 4095,
> --
> 2.16.1
>
commit 79a68b2631d8ec3e149081b1ecfb23509c040b4e
Author: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Date: Tue Mar 20 10:44:40 2018 +0100
net: dsa: mv88e6xxx: Fix name of switch 88E6141
The switch name is emitted in the kernel log, so having the right name
there is nice.
Fixes: 1558727a1c1b ("net: dsa: mv88e6xxx: Add support for ethernet switch 88E6141")
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [PATCH net-next v2 00/15] ARM: sun8i: r40: Add Ethernet support
From: Maxime Ripard @ 2018-05-03 13:12 UTC (permalink / raw)
To: David Miller
Cc: wens, mturquette, sboyd, peppe.cavallaro, robh+dt, mark.rutland,
broonie, linux-arm-kernel, linux-clk, devicetree, netdev,
clabbe.montjoie, icenowy
In-Reply-To: <20180502.110617.304411895589508709.davem@davemloft.net>
[-- Attachment #1: Type: text/plain, Size: 1261 bytes --]
Hi Dave,
On Wed, May 02, 2018 at 11:06:17AM -0400, David Miller wrote:
> From: Chen-Yu Tsai <wens@csie.org>
> Date: Wed, 2 May 2018 00:33:45 +0800
>
> > I should've mentioned that patches 3 ~ 10, and only these, should go
> > through net-next. sunxi will handle the remaining clk, device tree, and
> > soc driver patches.
>
> Ok, I just noticed this.
>
> Why don't you just post those patches separately as a series on their
> own then, in order to avoid confusion?
>
> Then you can adjust the patch series header posting to explain the
> non-net-next changes, where they got merged, and what they provide
> in order to faciliate the net-next changes.
I now that we usually have some feedback from non-net maintainers that
they actually prefer seeing the full picture (and I also tend to
prefer that as well) and having all the patches relevant to enable a
particular feature, even if it means getting multiple maintainers
involved.
Just to make sure we understood you fully, do you want Chen-Yu to
resend his serie following your comments, or was that just a general
remark for next time?
Thanks!
Maxime
--
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH v1 net-next] net: dsa: mv88e6xxx: Fix name string for 88E6141
From: Marek Behún @ 2018-05-03 13:06 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Greg Kroah-Hartman, Vivien Didelot,
Arkadi Sharshevsky, David S . Miller, Marek Behún
The structure was copied from 88E6341 but the name was not changed.
Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index e9600a82dc83..fae362020305 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3206,7 +3206,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
[MV88E6141] = {
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
.family = MV88E6XXX_FAMILY_6341,
- .name = "Marvell 88E6341",
+ .name = "Marvell 88E6141",
.num_databases = 4096,
.num_ports = 6,
.max_vid = 4095,
--
2.16.1
^ permalink raw reply related
* [PATCH v1 net-next] net: dsa: mv88e6xxx: 88E6141/6341 SERDES support
From: Marek Behún @ 2018-05-03 13:06 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Greg Kroah-Hartman, Vivien Didelot,
Arkadi Sharshevsky, David S . Miller, Marek Behún
The 88E6141/6341 switches (also known as Topaz) have 1 SGMII lane,
which can be configured the same way as the SERDES lane on 88E6390.
Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
drivers/net/dsa/mv88e6xxx/chip.c | 2 ++
drivers/net/dsa/mv88e6xxx/serdes.c | 20 ++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/serdes.h | 1 +
3 files changed, 23 insertions(+)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index eebda5ec9676..e9600a82dc83 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2426,6 +2426,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
.reset = mv88e6352_g1_reset,
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
+ .serdes_power = mv88e6341_serdes_power,
};
static const struct mv88e6xxx_ops mv88e6161_ops = {
@@ -2924,6 +2925,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
.reset = mv88e6352_g1_reset,
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
+ .serdes_power = mv88e6341_serdes_power,
};
static const struct mv88e6xxx_ops mv88e6350_ops = {
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index f3c01119b3d1..cd03a62946e3 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -227,3 +227,23 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
return 0;
}
+
+int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
+{
+ int err;
+ u8 cmode;
+
+ if (port != 5)
+ return 0;
+
+ err = mv88e6xxx_port_get_cmode(chip, port, &cmode);
+ if (err)
+ return err;
+
+ if ((cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) ||
+ (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII) ||
+ (cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX))
+ return mv88e6390_serdes_sgmii(chip, 0x15, on);
+
+ return 0;
+}
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index 5c1cd6d8e9a5..d7dc6decf69b 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -42,6 +42,7 @@
#define MV88E6390_SGMII_CONTROL_LOOPBACK BIT(14)
#define MV88E6390_SGMII_CONTROL_PDOWN BIT(11)
+int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
--
2.16.1
^ permalink raw reply related
* Re: [PATCH v1 net-next] net: dsa: mv88e6xxx: 88E6141/6341 SERDES support
From: Andrew Lunn @ 2018-05-03 13:15 UTC (permalink / raw)
To: Marek Behún
Cc: netdev, Greg Kroah-Hartman, Vivien Didelot, Arkadi Sharshevsky,
David S . Miller
In-Reply-To: <20180503130648.23225-1-marek.behun@nic.cz>
On Thu, May 03, 2018 at 03:06:48PM +0200, Marek Behún wrote:
> The 88E6141/6341 switches (also known as Topaz) have 1 SGMII lane,
> which can be configured the same way as the SERDES lane on 88E6390.
>
> Signed-off-by: Marek Behun <marek.behun@nic.cz>
> +int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
> +{
> + int err;
> + u8 cmode;
> +
> + if (port != 5)
> + return 0;
> +
> + err = mv88e6xxx_port_get_cmode(chip, port, &cmode);
> + if (err)
> + return err;
> +
> + if ((cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) ||
> + (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII) ||
> + (cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX))
> + return mv88e6390_serdes_sgmii(chip, 0x15, on);
Hi Marek
Please add a #define for this 0x15.
Otherwise, this looks good.
Andrew
^ permalink raw reply
* Re: [PATCH 1/2] ixgbe: release lock for the duration of ixgbe_suspend_close()
From: Alexander Duyck @ 2018-05-03 13:20 UTC (permalink / raw)
To: Pavel Tatashin
Cc: steven.sistare, daniel.m.jordan, LKML, Jeff Kirsher,
intel-wired-lan, Netdev, Greg KH
In-Reply-To: <20180503035931.22439-2-pasha.tatashin@oracle.com>
On Wed, May 2, 2018 at 8:59 PM, Pavel Tatashin
<pasha.tatashin@oracle.com> wrote:
> Currently, during device_shutdown() ixgbe holds rtnl_lock for the duration
> of lengthy ixgbe_close_suspend(). On machines with multiple ixgbe cards
> this lock prevents scaling if device_shutdown() function is multi-threaded.
>
> It is not necessary to hold this lock during ixgbe_close_suspend()
> as it is not held when ixgbe_close() is called also during shutdown but for
> kexec case.
>
> Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index afadba99f7b8..e7875b58854b 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -6748,8 +6748,15 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
> rtnl_lock();
> netif_device_detach(netdev);
>
> - if (netif_running(netdev))
> + if (netif_running(netdev)) {
> + /* Suspend takes a long time, device_shutdown may be
> + * parallelized this function, so drop lock for the
> + * duration of this call.
> + */
> + rtnl_unlock();
> ixgbe_close_suspend(adapter);
> + rtnl_lock();
> + }
>
> ixgbe_clear_interrupt_scheme(adapter);
> rtnl_unlock();
I'm not a fan of dropping the mutex while we go through
ixgbe_close_suspend. I'm concerned it will result in us having a
number of races on shutdown.
If anything, I think we would need to find a replacement for the mutex
that can operate at the per-netdev level if you are wanting to
parallelize this.
- Alex
^ permalink raw reply
* Re: [PATCH 1/2] ixgbe: release lock for the duration of ixgbe_suspend_close()
From: Pavel Tatashin @ 2018-05-03 13:30 UTC (permalink / raw)
To: alexander.duyck
Cc: Steven Sistare, Daniel Jordan, LKML, jeffrey.t.kirsher,
intel-wired-lan, netdev, gregkh
In-Reply-To: <CAKgT0UdocfEm9oXZ1dkEMari8m3OA4uVTrYg45uj9fk2V41bxQ@mail.gmail.com>
Hi Alex,
> I'm not a fan of dropping the mutex while we go through
> ixgbe_close_suspend. I'm concerned it will result in us having a
> number of races on shutdown.
I would agree, but ixgbe_close_suspend() is already called without this
mutex from ixgbe_close(). This path is executed also during machine
shutdown but when kexec'ed. So, it is either an existing bug or there are
no races. But, because ixgbe_close() is called from the userland, and a
little earlier than ixgbe_shutdown() I think this means there are no races.
> If anything, I think we would need to find a replacement for the mutex
> that can operate at the per-netdev level if you are wanting to
> parallelize this.
Yes, if lock is necessary, it can be replaced in this place (and added to
ixgbe_close()) with something scalable.
Thank you,
Pavel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox