Skip to content

Commit 1f3ccc3

Browse files
ffainellidavem330
authored andcommitted
net: systemport: Correclty disambiguate driver instances
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: d156576 ("net: systemport: Establish lower/upper queue mapping") Signed-off-by: Florian Fainelli <[email protected]> Reviewed-by: Vivien Didelot <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9faedd6 commit 1f3ccc3

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

drivers/net/ethernet/broadcom/bcmsysport.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,14 +2144,21 @@ static const struct net_device_ops bcm_sysport_netdev_ops = {
21442144
.ndo_select_queue = bcm_sysport_select_queue,
21452145
};
21462146

2147-
static int bcm_sysport_map_queues(struct net_device *dev,
2147+
static int bcm_sysport_map_queues(struct notifier_block *nb,
21482148
struct dsa_notifier_register_info *info)
21492149
{
2150-
struct bcm_sysport_priv *priv = netdev_priv(dev);
21512150
struct bcm_sysport_tx_ring *ring;
2151+
struct bcm_sysport_priv *priv;
21522152
struct net_device *slave_dev;
21532153
unsigned int num_tx_queues;
21542154
unsigned int q, start, port;
2155+
struct net_device *dev;
2156+
2157+
priv = container_of(nb, struct bcm_sysport_priv, dsa_notifier);
2158+
if (priv->netdev != info->master)
2159+
return 0;
2160+
2161+
dev = info->master;
21552162

21562163
/* We can't be setting up queue inspection for non directly attached
21572164
* switches
@@ -2174,6 +2181,7 @@ static int bcm_sysport_map_queues(struct net_device *dev,
21742181
if (priv->is_lite)
21752182
netif_set_real_num_tx_queues(slave_dev,
21762183
slave_dev->num_tx_queues / 2);
2184+
21772185
num_tx_queues = slave_dev->real_num_tx_queues;
21782186

21792187
if (priv->per_port_num_tx_queues &&
@@ -2201,7 +2209,7 @@ static int bcm_sysport_map_queues(struct net_device *dev,
22012209
return 0;
22022210
}
22032211

2204-
static int bcm_sysport_dsa_notifier(struct notifier_block *unused,
2212+
static int bcm_sysport_dsa_notifier(struct notifier_block *nb,
22052213
unsigned long event, void *ptr)
22062214
{
22072215
struct dsa_notifier_register_info *info;
@@ -2211,7 +2219,7 @@ static int bcm_sysport_dsa_notifier(struct notifier_block *unused,
22112219

22122220
info = ptr;
22132221

2214-
return notifier_from_errno(bcm_sysport_map_queues(info->master, info));
2222+
return notifier_from_errno(bcm_sysport_map_queues(nb, info));
22152223
}
22162224

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

0 commit comments

Comments
 (0)