[lkml]   [2018]   [May]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[PATCH 4.16 43/55] net: systemport: Correclty disambiguate driver instances
4.16-stable review patch.  If anyone has any objections, please let me know.


From: Florian Fainelli <>

[ Upstream commit 1f3ccc3c3fc26468be00392ef0b2c215f9c9d054 ]

While adding the DSA notifier, we will be sending DSA notifications with
info->master that is going to point to a particular net_device instance.

Our logic in bcm_sysport_map_queues() correctly disambiguates net_device
instances that are not covered by our own driver, but it will not make
sure that info->master points to a particular driver instance that we
are interested in. In a system where e.g: two or more SYSTEMPORT
instances are registered, this would lead in programming two or more
times the queue mapping, completely messing with the logic which does
the queue/port allocation and tracking.

Fix this by looking at the notifier_block pointer which is unique per
instance and allows us to go back to our driver private structure, and
in turn to the backing net_device instance.

Fixes: d156576362c0 ("net: systemport: Establish lower/upper queue mapping")
Signed-off-by: Florian Fainelli <>
Reviewed-by: Vivien Didelot <>
Signed-off-by: David S. Miller <>
Signed-off-by: Greg Kroah-Hartman <>
drivers/net/ethernet/broadcom/bcmsysport.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -2052,14 +2052,21 @@ static const struct net_device_ops bcm_s
.ndo_select_queue = bcm_sysport_select_queue,

-static int bcm_sysport_map_queues(struct net_device *dev,
+static int bcm_sysport_map_queues(struct notifier_block *nb,
struct dsa_notifier_register_info *info)
- struct bcm_sysport_priv *priv = netdev_priv(dev);
struct bcm_sysport_tx_ring *ring;
+ struct bcm_sysport_priv *priv;
struct net_device *slave_dev;
unsigned int num_tx_queues;
unsigned int q, start, port;
+ struct net_device *dev;
+ priv = container_of(nb, struct bcm_sysport_priv, dsa_notifier);
+ if (priv->netdev != info->master)
+ return 0;
+ dev = info->master;

/* We can't be setting up queue inspection for non directly attached
* switches
@@ -2082,6 +2089,7 @@ static int bcm_sysport_map_queues(struct
if (priv->is_lite)
slave_dev->num_tx_queues / 2);
num_tx_queues = slave_dev->real_num_tx_queues;

if (priv->per_port_num_tx_queues &&
@@ -2109,7 +2117,7 @@ static int bcm_sysport_map_queues(struct
return 0;

-static int bcm_sysport_dsa_notifier(struct notifier_block *unused,
+static int bcm_sysport_dsa_notifier(struct notifier_block *nb,
unsigned long event, void *ptr)
struct dsa_notifier_register_info *info;
@@ -2119,7 +2127,7 @@ static int bcm_sysport_dsa_notifier(stru

info = ptr;

- return notifier_from_errno(bcm_sysport_map_queues(info->master, info));
+ return notifier_from_errno(bcm_sysport_map_queues(nb, info));

#define REV_FMT "v%2x.%02x"

 \ /
  Last update: 2018-05-18 11:16    [W:0.140 / U:8.648 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site